grep, um vor und nach dem Spiel die Zeilen Nth und Mth zurückzugeben


12

Ich weiß, dass ich mit grep die Felder verwenden -Aund -Bvorherige 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?


1
Sie könnten es tun, indem Sie es in sed leiten. Ich habe das gerade getestet und es hat funktioniert, aber es hat nur funktioniert, wenn es 1 genaue Übereinstimmung in der Datei gab: grep -r -i -B 5 -A 5 "match" | sed -e 1b -e '$!d'
Terrance

@Terrance danke für den Vorschlag, wie Sie erwähnen, da ich Tausende von Zeilen sammle, wird dies nicht funktionieren.
Chollida

Ich glaube nicht, dass grep von alleine funktionieren wird ... Ich arbeite an einem Bash-Skript für Sie
Joshua Besneatte

Kein Problem! Interessiert, welche Antworten Sie erhalten. =)
Terrance

Ist dies in einer Datei oder in mehreren Dateien?
Joshua Besneatte

Antworten:


1

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


Willkommen bei AskUbuntu, danke für die Antwort. Sie müssen ein CLI-Beispiel bereitstellen, mit dem dieses spezielle Problem gelöst werden kann, anstatt einen Link zur Sift-Website bereitzustellen. Dies ist eine Frage und Antwort, danke.
Bernard Wei

12

Wenn:

cat file
a
b
c
d
e
f match
g
h
i match
j
k
l
m
n
o

Dann:

awk '
    {line[NR] = $0} 
    /match/ {matched[NR]} 
    END {
        for (nr in matched)
            for (n=nr-5; n<=nr+5; n+=5) 
                print line[n]
    }
' file
a
f match
k
d
i match
n

+1, aber könnten Sie die Semantik von erklären /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?
Joe

Dies ist eine merkwürdige Kuriosität: Wenn Sie auf ein Array-Element ohne Zuweisung verweisen, wird dieser Schlüssel dem Array hinzugefügt (ohne Wert). Dann wird dieser Schlüssel im Ausdruck angezeigt key in array. Ich erinnere mich an die Zeilennummern, in denen das Muster erscheint
Glenn Jackman,

6

Dies ist im Grunde Glenns Lösung, die jedoch mit Bash, Grep und sed implementiert wurde.

grep -n match file |
    while IFS=: read nr _; do
        sed -ns "$((nr-5))p; $((nr))p; $((nr+5))p" file
    done

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.


6

Es kann nicht nur damit gemacht werden grep. Wenn es edeine Option ist:

ed -s file << 'EOF' 
g/match/-5p\
+5p\
+5p
EOF  

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.


5
@ubashu Glaubst du, es wird hilfreicher für das OP sein, eine einfache Wohnung zu geben, "es kann nicht mit grep gemacht werden"? Ich biete eine meiner Meinung nach gute Alternative zur Lösung des OP-Problems. In der Hilfe: "Worum geht es bei der Frage? Stellen Sie sicher, dass Ihre Antwort dies bietet - oder eine praktikable Alternative. Die Antwort kann" Tun Sie das nicht "sein, sollte aber auch" Versuchen Sie dies stattdessen "enthalten. . "
JoL

edist immer eine Antwort, weil edder Standard-Texteditor ist.
Nachtisch

5
@ubashu Obwohl es keine grepAntwort 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.
Thomas Ward

5
awk '/match/{system("sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME)}' infile

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)sedmatch

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 awkOptionen selbst zusammenhängt, sollte außerhalb der Anführungszeichen liegen. Also die unten sed :

"sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME

übersetzen in:

sed -n "NR-5p; NRp; NR+5p" FILENAME

NRist die Zeilennummer , die mit dem Muster übereinstimmt , matchund FILENAMEist die Verarbeitung der aktuellen Dateinamen vorbei awk.


2

Verwenden der Beispieltextdatei von @ glenn und Verwenden von Perl anstelle von awk:

$ perl -n0E 'say /(.*\n)(?=(?:.*\n){4}(.*match.*\n)(?:.*\n){4}(.*\n))/g' ex

gibt die gleichen Ergebnisse, läuft aber schneller:

a
f match
k
d
i match
n

João, du tauchst in der LQ-Überprüfungswarteschlange auf und @waltinator hat für das Löschen gestimmt. Sei also das nächste Mal ein bisschen ausführlicher ... ;-) Auch +1, um dich aus der LQ-Warteschlange herauszuholen ... : P.
Fabby

1
@JJoao Überprüfungswarteschlange von geringer Qualität. Ihre Antwort wurde wahrscheinlich dort abgeholt, weil es sich um 90% Code handelte.
Wjandrea

1
@JJoao Die 90% Zahl ist nur meine Art, es zu erklären. Ich weiß nicht, welche Heuristiken tatsächlich verwendet werden.
Wjandrea

1
Menos Café, mehr Escrita! @JJoao : D ;-): D
Fabby

1
@ Fabby: Sem Café Nada Funciona: D - wahrscheinlich würde es in der LCQ (= niedrige
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.