Ich brauche Hilfe bei Grep, um in einem Abschnitt zu beginnen


8

Ich habe einige Textdateien, aus denen ich einen Codeabschnitt abrufen möchte. Das Ziel, das ich zu erreichen versuche, ist, die Ansicht an einer bestimmten Zeile zu starten und dann alles darunter lesen zu können. Zum Beispiel. Wie kann ich im folgenden Text die Textdatei am gelben Startpunkt anzeigen? Ich möchte den Inhalt von "gelb" sowie alles darunter anzeigen, unabhängig davon, um welchen Inhalt es sich handelt.

green
blue
cyan
magenta
purple
brown
yellow
red
orange
more orange
more blue
this is enough

Antworten:


9

AWK- Verwendung AWK- das ist so einfach wie möglich:

awk '/yellow/,0' textfile.txt

Probelauf

$ awk '/yellow/,0' textfile.txt                                
yellow
red
orange
more orange
more blue
this is enough

Grep

Sie können auch verwenden , grepmit --after-contextOption, gewisse Linien nach dem Spiel zu drucken

grep 'yellow' --after-context=999999  textfile.txt

Für die automatische Einstellung des Kontexts können Sie verwenden $(wc -l textfile.txt). Die Grundidee ist, dass, wenn Sie eine erste Zeile als Übereinstimmung haben und alles nach dieser Übereinstimmung drucken möchten, Sie die Anzahl der Zeilen in der Datei minus 1 kennen müssen. Glücklicherweise --after-contextwerden keine Fehler über die Anzahl der Zeilen ausgegeben Zeilen, so dass Sie die Nummer vollständig außerhalb des Bereichs angeben können, aber falls Sie es nicht wissen, reicht die Gesamtzahl der Zeilen aus

$ grep 'yellow' --after-context=$(wc -l < textfile.txt) textfile.txt
yellow
red
orange
more orange
more blue
this is enough

Wenn Sie den Befehl kürzen möchten, --after-contextist dies die gleiche Option wie -Aund $(wc -l textfile.txt), wird auf die Anzahl der Zeilen gefolgt vom Dateinamen erweitert. Auf diese Weise tippen Sie textfile.txtnur einmal

grep "yellow" -A $(wc -l textfile.txt)

Python

skolodya@ubuntu:$ ./printAfter.py textfile.txt                                 
yellow
red
orange
more orange
more blue
this is enough

DIR:/xieerqi
skolodya@ubuntu:$ cat ./printAfter.py                                          
#!/usr/bin/env python
import sys

printable=False
with open(sys.argv[1]) as f:
     for line in f:
        if "yellow" in line:
           printable=True
        if printable:
           print line.rstrip('\n')

Oder alternativ ohne printableFlagge

#!/usr/bin/env python
import sys

with open(sys.argv[1]) as f:
     for line in f:
        if "yellow" in line:
          for lines in f: # will print remaining lines
             print lines.rstrip('\n')
          exit()

Sie können den grepBefehl vereinfachen grep "yellow" -A $(wc -l textfile.txt).
Byte Commander

@ByteCommander yup, kann auch gemacht werden. Nur volle Option für Klarheit verwendet
Sergiy Kolodyazhnyy

1
@ ByteCommander Was für ein schöner Hack. Leider funktioniert es nur, weil der Dateiname keine Leerzeichen enthält.
Kasperd

@kasperd Oh ja, du hast recht. In diesem Fall müssten Sie auf Sergs ursprünglichen Befehl zurückgreifen grep "yellow" -A $(wc -l < "my colors.txt") "my colors.txt".
Byte Commander

5

Sie können es tun durch:

awk '/yellow/{f=1}f' file

Dabei ist "Datei" der Dateiname, der Ihren Text enthält.


Große Köpfe denken gleich> :)
Sergiy Kolodyazhnyy

5

Nicht grep, aber mit sed:

sed -n '/^yellow$/,$p' file
  • -n: verhindert das Drucken
  • /^yellow$/,$: Adressbereich, der vom ersten Auftreten einer Zeile yellowbis zur letzten Zeile einschließlich reicht
  • p: druckt die Zeilen im Adressbereich
% sed -n '/^yellow$/,$p' file
yellow
red
orange
more orange
more blue
this is enough

5

Spät zur Party :)

Verwenden von grep:

grep -Pzo '(?s)\n\Kyellow\n.*' file.txt
  • -P ermöglicht es uns, Perl-kompatibles Regex zu verwenden

  • -z Trennt die Eingabedatei durch ASCII NUL und nicht durch die neue Zeile

  • -o nimmt nur die gewünschte Portion

  • (?s)ist der DOTALL-Modifikator, der es uns ermöglicht, Zeilenumbrüche mit Token .(beliebige Zeichen) abzugleichen.

  • In \n\K, \nstimmt mit einer neuen Zeile überein, \Kverwirft die Übereinstimmung

  • yellow\n.*Übereinstimmungen yellowgefolgt von einem Zeilenumbruch und alles, was danach folgt, wird ebenfalls ausgewählt und in der Ausgabe angezeigt.

Beispiel:

% grep -Pzo '(?s)\n\Kyellow\n.*' file.txt
yellow
red
orange
more orange
more blue
this is enough

Mit wenig python:

#!/usr/bin/env python2
with open('file.txt') as f:
    lines = f.readlines()
    print ''.join(lines[lines.index('yellow\n'):])
  • lines ist die Liste, die alle Zeilen der Datei enthält (auch mit nachgestellten Zeilenumbrüchen)

  • lines.index('yellow\n')gibt uns den niedrigsten Index, lineswo yellow\ngefunden wird

  • lines[lines.index('yellow\n'):]verwendet List Slicing, um die Portion von Anfang yellow\nbis Ende zu erhalten

  • join verbindet die Elemente der Liste, um sie als Zeichenfolge auszugeben


Schön, aber Sie sollten erwähnen, dass der Python-Code nur ganze Zeilen findet, die gleich "gelb" sind. Er erkennt beispielsweise keine Zeilen wie "mehr gelb".
Byte Commander

@ByteCommander Aus dem Beispiel von OP denke ich, dass es klar ist, dass sie nur yellowin der Zeile übereinstimmen wollen. Auch wenn dies nicht der Fall ist, müssen wir pythondas Algo ändern .
heemayl

Ja sicher. Das war sowieso keine Kritik, nur ein Hinweis, um die Antwort zu verbessern. Jemand anderes, der dies liest, könnte annehmen, dass der Code wie funktioniert grepund nicht nur mit vollständigen Zeilen übereinstimmt. Ich habe übrigens gestimmt.
Byte Commander

4

Da sich die Frage auf das Anzeigen der Datei bezieht , gibt es immer den guten alten

less +/yellow file

Wusste nicht, lessdass ich das kann. Sehr schön !
Sergiy Kolodyazhnyy
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.