it-swarm.com.de

grep + A: drucke alles nach dem Match

Hallo, ich habe eine Datei mit einer Liste von URLs, sieht wie folgt aus:

file1:

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

Ich möchte alle Datensätze abrufen, nachdem: http://www.yahoo.com , die Ergebnisse sehen wie folgt aus:

file2:

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

Ich weiß, dass ich grep verwenden könnte, um die Zeilennummer zu ermitteln, in der yahoo.com verwendet

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

Aber ich weiß nicht, wie ich die Datei nach Zeilennummer 3 erhalten soll. Außerdem weiß ich, dass in grep-A eine Markierung vorhanden ist, mit der die Zeilen nach dem Abgleich gedruckt werden. Sie müssen jedoch angeben, wie viele Zeilen Sie nach dem Abgleich benötigen. Ich frage mich, ob es etwas gibt, um dieses Problem zu umgehen. Mögen:

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

Ich weiß, wir könnten die Zeilennummer verwenden, die ich bekommen habe, und wc -l, um die Anzahl der Zeilen nach yahoo.com zu erhalten. Fühlt sich jedoch ziemlich lahm an.

Freuen Sie sich auf eine praktische und einfache Lösung. Zögern Sie nicht, mich dafür zu kritisieren, dass ich das Problem gleich zu Beginn komplexere, und awk- und sed-Befehle sind ebenfalls willkommen!

30
B.Mr.W.

Awk

Wenn es Ihnen nichts ausmacht, awk zu verwenden:

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

Dieses Skript besteht aus zwei Teilen:

/yahoo/ { y = 1; next }
y

Der erste Teil besagt, dass, wenn wir auf eine Zeile mit yahoo stoßen, wir die Variable y = 1 setzen und diese Zeile dann überspringen (der Befehl next springt zur nächsten Zeile, also überspringen weitere Bearbeitung in der aktuellen Zeile). Ohne den Befehl next wird die Zeile yahoo gedruckt.

Der zweite Teil ist eine kurze Hand für:

y != 0 { print }

Das heißt, wenn die Variable y für jede Zeile nicht Null ist, geben wir diese Zeile aus. Wenn Sie in awk auf eine Variable verweisen, wird diese Variable erstellt und ist je nach Kontext entweder null oder eine leere Zeichenfolge. Vor der Begegnung yahoo hat die Variable y den Wert 0, sodass das Skript nichts ausgibt. Nach der Begegnung yahoo ist y 1, daher wird jede Zeile danach gedruckt.

Sed

Oder mit sed löscht das Folgende alles bis einschließlich der Zeile mit yahoo:

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

Dies ist mit sed viel einfacher als mit grep. sed kann jeden seiner Ein-Buchstaben-Befehle auf eine Reihe von Zeilen anwenden. Die allgemeine Syntax hierfür ist

START , STOP COMMAND

außer ohne Leerzeichen. START und STOP können jeweils eine Zahl sein (was "Zeilennummer N" bedeutet, beginnend mit 1); ein Dollarzeichen ("das Ende der Datei") oder ein Regexp in Schrägstrichen ("die erste Zeile, die diesem Regexp entspricht"). (Die genauen Regeln sind etwas komplizierter; das GNU sed Handbuch hat mehr Details .)

So können Sie machen, was Sie wollen:

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

Das Zeichen -n Bedeutet "nichts drucken, außer es wurde ausdrücklich dazu aufgefordert", und das Zeichen -e Bedeutet "ab dem ersten Auftreten einer Zeile, die mit dem regulären Ausdruck /http:\/\/www\.yahoo\.com/ Übereinstimmt, bis zum Ende der Datei, print. "

Dies schließt die Zeile mit http://www.yahoo.com/ In die Ausgabe ein. Wenn Sie alles nach diesem Punkt wollen, aber nicht diese Linie selbst, ist der einfachste Weg dies zu tun, die Operation umzukehren:

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

was bedeutet, dass "für Zeile 1 bis zur ersten Zeile, die mit dem regulären Ausdruck /http:\/\/www\.yahoo\.com/ übereinstimmt, d die Zeile löscht" (und dann implizit alles andere ausgibt; beachte, dass -n ist diesmal nicht benutzt).

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

Oder golfen

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

Ergebnis

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

Das geht am einfachsten in Perl:

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

Mit anderen Worten, drucken Sie alle Zeilen, die sind nicht zwischen Zeile 1 und dem ersten Auftreten dieses Musters liegen.

3
tchrist

mit Skript

#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