web-dev-qa-db-fra.com

grep + A: tout imprimer après la correspondance

Salut j'ai un fichier contient une liste d'URL, ressemble à ci-dessous:

fichier1:

http://www.google.com
http://www.bing.com
http://www.yahoo.com
http://www.baidu.com
http://www.yandex.com
....

Je veux obtenir tous les enregistrements après: http://www.yahoo.com , les résultats ressemblent à ci-dessous:

fichier2:

http://www.baidu.com
http://www.yandex.com
....

Je sais que je pourrais utiliser grep pour trouver le numéro de ligne où se trouve yahoo.com en utilisant

$grep -n 'http://www.yahoo.com' file1
3 http://www.yahoo.com

Mais je ne sais pas comment obtenir le fichier après la ligne numéro 3. De plus, je sais qu'il y a un drapeau dans grep -A imprimer les lignes après votre correspondance. Cependant, vous devez spécifier le nombre de lignes souhaitées après la correspondance. Je me demande s'il y a quelque chose pour contourner ce problème. Comme:

PSEUDO CODE:
$ grep -n 'http://www.yahoo.com' -A all file1 > file2 

Je sais que nous pourrions utiliser le numéro de ligne que j'ai obtenu et wc -l pour obtenir le nombre de lignes après yahoo.com, cependant.

Dans l'attente d'une solution pratique et facile. N'hésitez pas à me critiquer pour avoir complexifié le problème dès le début et les commandes awk et sed sont également les bienvenues!

30
B.Mr.W.

Awk

Si cela ne vous dérange pas d'utiliser awk:

awk '/yahoo/{y=1;next}y' data.txt

Ce script se compose de deux parties:

/yahoo/ { y = 1; next }
y

La première partie déclare que si nous rencontrons une ligne avec yahoo, nous définissons la variable y = 1, puis sautons cette ligne (la commande next passera à la ligne suivante, donc sautons tout traitement ultérieur sur la ligne actuelle). Sans la commande next, la ligne yahoo sera imprimée.

La deuxième partie est une brève description de:

y != 0 { print }

Ce qui signifie que pour chaque ligne, si la variable y est non nulle, nous imprimons cette ligne. Dans awk, si vous faites référence à une variable, cette variable sera créée et sera soit zéro soit une chaîne vide, selon le contexte. Avant la rencontre yahoo, la variable y est 0, donc le script n'imprime rien. Après la rencontre yahoo, y est 1, donc chaque ligne après cela sera imprimée.

Sed

Ou, en utilisant sed, ce qui suit supprimera tout jusqu'à et y compris la ligne avec yahoo:

sed '1,/yahoo/d' data.txt 
44
Hai Vu

C'est beaucoup plus facile à faire avec sed qu'avec grep. sed peut appliquer n'importe laquelle de ses commandes à une lettre à une plage inclusive de lignes; la syntaxe générale est

START , STOP COMMAND

sauf sans espaces. START et STOP peuvent chacun être un nombre (signifiant "numéro de ligne N", à partir de 1); un signe dollar (signifiant "la fin du fichier"), ou une expression régulière entourée de barres obliques, signifiant "la première ligne qui correspond à cette expression régulière". (Les règles exactes sont légèrement plus compliquées; le manuel GNU sed contient plus de détails .))

Donc, vous pouvez faire ce que vous voulez comme ça:

sed -n -e '/http:\/\/www\.yahoo\.com/,$p' file1 > file2

Le -n signifie "n'imprime rien sauf indication contraire", et le -e directive signifie "dès la première apparition d'une ligne qui correspond à l'expression rationnelle /http:\/\/www\.yahoo\.com/ à la fin du fichier, print. "

Cela comprendra la ligne avec http://www.yahoo.com/ dessus dans la sortie. Si vous voulez tout après ce point mais pas cette ligne elle-même, la façon la plus simple de le faire est d'inverser l'opération:

sed -e '1,/http:\/\/www\.yahoo\.com/d' file1 > file2

ce qui signifie "pour la ligne 1 jusqu'à la première ligne correspondant à l'expression rationnelle /http:\/\/www\.yahoo\.com/, dsupprimez la ligne "(puis, implicitement, imprimez tout le reste; notez que -n n'est pas utilisé cette fois).

13
zwol
awk '/yahoo/ ? c++ : c' file1

Ou joué au golf

awk '/yahoo/?c++:c' file1

Résultat

 http://www.baidu.com 
 http://www.yandex.com 
7
Steven Penny

Cela se fait le plus facilement en Perl:

Perl -ne 'print unless 1 .. m(http://www\.yahoo\.com)' file

En d'autres termes, imprimez toutes les lignes qui ne sont pas entre la ligne 1 et la première occurrence de ce motif.

3
tchrist

en utilisant un script

#get index of yahoo Word
index=`grep -n "yahoo" filepath | cut -d':' -f1`
#get total number of lines in file
totallines=`wc -l filepath | cut -d' ' -f1`
#subtract totallines with index
result=`expr $total - $index`
#gives the desired output
grep -A $result "yahoo" filepath
2
user1502952