Potrzebuję pomocy z Grepem, aby zacząć od sekcji

8

Mam kilka plików tekstowych, z których chcę grepować fragment kodu. Celem, który staram się osiągnąć, jest rozpoczęcie widoku od określonej linii, a następnie umiejętność przeczytania wszystkiego poniżej. Na przykład. W poniższym tekście, jak wyświetlić plik tekstowy w punkcie początkowym koloru żółtego. Chcę zobaczyć zawartość „żółtego”, a także wszystko pod nim, niezależnie od tego, co to jest.

green
blue
cyan
magenta
purple
brown
yellow
red
orange
more orange
more blue
this is enough
John Smith
źródło

Odpowiedzi:

9

Korzystanie z AWKAWK - to najprostsze, jakie można uzyskać:

awk '/yellow/,0' textfile.txt

Przykładowy przebieg

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

Grep

Można również skorzystać grepz --after-contextopcji, aby wydrukować pewną ilość wierszy po meczu

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

Do automatycznego ustawienia kontekstu możesz użyć $(wc -l textfile.txt). Podstawową ideą jest to, że jeśli masz pierwszy wiersz jako dopasowanie i chcesz wydrukować wszystko po tym dopasowaniu, musisz znać liczbę wierszy w pliku minus 1. Na szczęście --after-contextnie wyrzuci błędów dotyczących liczby linii, więc możesz podać jej liczbę całkowicie poza zasięgiem, ale w przypadku, gdy jej nie znasz, zrobi to całkowita liczba linii

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

Jeśli chcesz skrócić, polecenie --after-contextjest takie samo, jak -Ai $(wc -l textfile.txt), zostanie rozszerzone do liczby wierszy, po których następuje nazwa pliku. W ten sposób piszesz textfile.txttylko raz

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

Pyton

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

Lub alternatywnie bez printableflagi

#!/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()
Sergiy Kolodyazhnyy
źródło
Możesz uprościć greppolecenie do grep "yellow" -A $(wc -l textfile.txt).
Bajt Dowódca
@ByteCommander tak, można to zrobić. Właśnie użyłem pełnej opcji dla jasności
Sergiy Kolodyazhnyy
1
@ByteCommander What a lovely hack. Niestety działa tylko dlatego, że w nazwie pliku nie ma spacji.
kasperd
@kasperd O tak, masz rację. W takim przypadku musiałbyś wrócić do pierwotnego polecenia Serga grep "yellow" -A $(wc -l < "my colors.txt") "my colors.txt".
Bajt Dowódca
5

Możesz to zrobić przez:

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

gdzie „plik” to nazwa pliku zawierającego tekst.

Pilot 6
źródło
Wielkie umysły myślą podobnie> :)
Sergiy Kolodyazhnyy
5

Nie grep, ale używając sed:

sed -n '/^yellow$/,$p' file
  • -n: hamuje drukowanie
  • /^yellow$/,$: zakres adresów, który rozpoczyna się od pierwszego wystąpienia wiersza pasującego dokładnie yellowdo ostatniego wiersza włącznie
  • p: drukuje linie w zakresie adresów
% sed -n '/^yellow$/,$p' file
yellow
red
orange
more orange
more blue
this is enough
kos
źródło
5

Późno na imprezę :)

Używanie grep:

grep -Pzo '(?s)\n\Kyellow\n.*' file.txt
  • -P umożliwia nam korzystanie z Regex zgodnego z Perl

  • -z sprawia, że ​​plik wejściowy jest oddzielany przez ASCII NUL, a nie nowy wiersz

  • -o zajmuje tylko żądaną porcję

  • (?s)jest modyfikatorem DOTALL, umożliwia dopasowanie nowej linii za pomocą tokena .(dowolnego znaku)

  • W \n\K, \ndopasowuje nowy wiersz, \Kodrzuca dopasowanie

  • yellow\n.*dopasowania, yellowpo których następuje nowa linia i wszystko po tym jest również zaznaczone i pokazane w danych wyjściowych.

Przykład:

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

Używając mało python:

#!/usr/bin/env python2
with open('file.txt') as f:
    lines = f.readlines()
    print ''.join(lines[lines.index('yellow\n'):])
  • lines jest listą zawierającą wszystkie linie pliku (również z końcowymi znakami nowej linii)

  • lines.index('yellow\n')daje nam najniższy wskaźnik tego, linesgdzie yellow\nznaleziono

  • lines[lines.index('yellow\n'):]użyje wycinania list, aby uzyskać porcję od początku yellow\ndo końca

  • join połączy elementy listy i wyśle ​​jako ciąg

heemayl
źródło
Fajnie, ale powinieneś wspomnieć, że kod Pythona znajduje tylko całe linie, które są równe „żółtemu”, nie wykrywa np. Linii takich jak „bardziej żółty”.
Bajt Dowódca
@ByteCommander Z przykładu OP myślę, że jest jasne, że chcą dopasować tylko yelloww linii .. również, jeśli tak nie jest, musimy zmienić pythonjego algo ..
heemayl
Tak, jasne. To i tak nie była krytyka, tylko wskazówka, by poprawić odpowiedź. Ktoś czytający to może założyć, że kod działa podobnie grepi nie pasuje tylko do pełnych linii. Głosowałem za btw.
Bajt Dowódca
4

Ponieważ pytanie dotyczy oglądania pliku, zawsze jest dobre

less +/yellow file
steeldriver
źródło
Nie wiedziałem less, że mogę to zrobić. Bardzo dobrze !
Sergiy Kolodyazhnyy