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

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

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

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

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


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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.