Jak uzyskać linię za pomocą wzorca przed numerem linii?

1

Muszę uzyskać linię pasującą do wzorca przed określoną liczbą linii pliku.

Przykład:

linenum 1.fruits
linenum 2.cherry
linenum 3.apple
.
.
linenum 7.orange
linenum 8.apple2
.
.
.
linenum 20.strawberry

Z powyższego pliku chcę line8. Wiem, że znajdzie się powyżej linii 20 i wiem, że ta linia zawiera apple.

Anthony
źródło
1
Co chcesz zrobić z line8? Czego próbowałeś Większość pytań można odpowiedzieć tutaj .
AFH,
1
Z jakimi kryteriami (oprócz „ maapple ”) pracujesz? Tylko jakaś linia powyżej linii 20, która ma apple?
Attie
Dodaj kontekst i pokaż swoje wysiłki, w przeciwnym razie będzie to ćwiczenie do nauki sed.
simlev

Odpowiedzi:

1

Pomimo tego, że tag jest , moja odpowiedź nie działa sed.

Następujące polecenie pobiera pierwsze 19 wierszy, odrzuca te bez apple, a następnie zwraca ostatni wiersz z tego, co zostało:

head -n 19 | grep "apple" | tail -n 1

Aby przetworzyć plik o nazwie file.txt:

<file.txt head -n 19 | grep "apple" | tail -n 1
Kamil Maciorowski
źródło
1

Oto rozwiązanie wykorzystujące sed:

sed -n '20,$d;/apple/h;19{x;p}'
  • -n - pomija drukowanie linii
  • 20,$d- dla dowolnej linii od 20do końca pliku ( $) usuń ( d)
  • /apple/h- dla każdego wiersza, który pasuje do wyrażenia regularnego /apple/, skopiuj go do „ hold space ” ( h)
  • 19{x;p}- w linii 19zamień wzór i przytrzymaj spacje ( x) i wydrukuj przestrzeń wzoru ( p)

Zauważ, że konieczne jest użycie linii 19do ostatecznego wydruku, ponieważ wszystkie linie po tym są usuwane. W przeciwnym razie możesz użyć adresu „ ostatniej linii ” - $.


W tym teście dodałem applewiersz 23.

$ sed -n '20,$d;/apple/h;19{x;p}' < file
linenum 8.apple2
Attie
źródło
0

To samo rozwiązanie, co już opublikowane, tym razem w Perlu:

perl -lane 'if(1..19 and /apple/){$a=$_} END{print $a}' input.txt

i AWK:

awk 'NR<20 && /apple/ {a=$0} END{print a}' input.txt
simlev
źródło