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.