Ich weiß, dass ich mit grep die Felder verwenden -A
und -B
vorherige und nächste Zeilen aus einem Match ziehen kann.
Sie ziehen jedoch alle Zeilen zwischen den Übereinstimmungen ein, basierend auf der Anzahl der angegebenen Zeilen.
grep -r -i -B 5 -A 5 "match"
Ich möchte nur die 5 erhalte th Linie vor einem Spiel und die 5 - ten Zeile nach dem Spiel neben der angepassten Linie und steigen Sie nicht die Grenzen zwischen.
Gibt es eine Möglichkeit, dies mit dem zu tun grep
?
command-line
grep
awk
Chollida
quelle
quelle
grep -r -i -B 5 -A 5 "match" | sed -e 1b -e '$!d'
Antworten:
Das Werkzeug, das Sie verwenden möchten, heißt Sieben. Dies ist im Grunde ein Grep auf Steroiden. Grep parallel. Sift bietet eine Vielzahl von Optionen, um genau das zu tun, was Sie möchten - insbesondere, um eine bestimmte Zeile in Bezug auf eine oder mehrere Übereinstimmungen zurückzugeben, denen möglicherweise Text folgt oder nicht folgt.
Es wundert mich, dass Sift kein Mainstream-Gnu ist, da es in der Go-Sprache geschrieben wurde, aber unter Linux einwandfrei installiert wird. Die IT sucht parallel mit allen cpus-großen Textmengen, wobei grep nur Wochen braucht, um dasselbe zu tun.
Website sieben - siehe Beispiele
quelle
Wenn:
Dann:
quelle
/match/ {matched[NR]}
? Ich habe noch nie ein Array oder eine Variable als ganzen Befehl gesehen. Wird die aktuelle Datensatznummer jeder übereinstimmenden Zeile in das Array eingefügt?key in array
. Ich erinnere mich an die Zeilennummern, in denen das Muster erscheintDies ist im Grunde Glenns Lösung, die jedoch mit Bash, Grep und sed implementiert wurde.
Beachten Sie, dass Zeilennummern kleiner als 1 einen sed-Fehler verursachen und Zeilennummern größer als die Anzahl der Zeilen in der Datei nichts drucken.
Dies ist nur das absolute Minimum. Um es rekursiv arbeiten zu lassen und die oben genannten Zeilennummernfälle zu behandeln, wäre etwas Arbeit erforderlich.
quelle
Es kann nicht nur damit gemacht werden
grep
. Wenn esed
eine Option ist:Das Skript sagt im Grunde: Für jede Übereinstimmung von / match / drucken Sie die Zeile 5 Zeilen davor, dann 5 Zeilen danach und dann 5 Zeilen danach.
quelle
ed
ist immer eine Antwort, weiled
der Standard-Texteditor ist.grep
Antwort ist, ist die Antwort "Sie können es nicht mit X machen, aber Sie können es mit Y machen, hier ist wie" immer noch eine gültige Antwort, da Sie nicht nur die Frage von OP beantworten, sondern auch eine Alternative anbieten das würde funktionieren. Dies ist hier eine gültige Antwort.Hier verwenden wir awk ‚s - Funktion außerhalb zu rufen Befehl , um die Linien zu drucken , die awk mit Muster verglichen mit 5 - ten Zeilen vor und nach dem Spiel.
system(command)
sed
match
Die Syntax ist einfach. Sie müssen nur den externen Befehl selbst in doppelte Anführungszeichen und seine Schalter setzen und die Dinge umgehen, die Sie genau an den Befehl übergeben möchten. Alles andere, was mit den
awk
Optionen selbst zusammenhängt, sollte außerhalb der Anführungszeichen liegen. Also die unten sed :übersetzen in:
NR
ist die Zeilennummer , die mit dem Muster übereinstimmt ,match
undFILENAME
ist die Verarbeitung der aktuellen Dateinamen vorbeiawk
.quelle
Verwenden der Beispieltextdatei von @ glenn und Verwenden von Perl anstelle von awk:
gibt die gleichen Ergebnisse, läuft aber schneller:
quelle