Mam plik, który wygląda następująco:

this name
this age

Remove these lines and space above.
Remove here too and space below

Keep everything below here. 

Nie chcę zakodować na stałe 2, ponieważ liczba wierszy zawierających „to” może się zmienić. Jak mogę usunąć 4 wiersze po ostatnim wystąpieniu ciągu. Próbuję sed -e '/this: /{n;N;N;N;N;d}', ale kasuję po pierwszym wystąpieniu ciągu.

0
programminglearner 3 kwiecień 2020, 21:20

3 odpowiedzi

Najlepsza odpowiedź

Czy mógłbyś spróbować podążać.

awk '
FNR==NR{
  if($0~/this/){
    line=FNR
  }
  next
}
FNR<=line || FNR>(line+4)
'  Input_file Input_file

Wynik będzie następujący z pokazanymi próbkami.

this: name
this: age
Keep everything below here.
4
RavinderSingh13 3 kwiecień 2020, 18:28

To może zadziałać dla Ciebie (GNU sed):

sed -E ':a;/this/n;//ba;$!N;$!ba;s/^([^\n]*\n?){4}//;/./!d' file 

Jeśli przestrzeń wzorca (PS) zawiera this, wydrukuj PS i pobierz następną linię.

Jeśli następujący wiersz zawiera this powtórz.

Jeśli bieżąca linia nie jest ostatnią linią, dołącz następną linię i powtórz.

W przeciwnym razie usuń pierwsze cztery wiersze PS i wydrukuj pozostałą część.

O ile PS nie jest pusty, w takim przypadku całkowicie usuń PS.

N.B. Spowoduje to odczytanie pliku tylko raz. Również OP mówi

Jak mogę usunąć 4 wiersze po ostatnim wystąpieniu ciągu

Jednak przykład wydaje się przewidywać usunięcie 5 wierszy.

0
potong 4 kwiecień 2020, 17:01

Możesz również użyć tej drobnej zmiany, aby oryginalne polecenie sed działało.

sed '/^this:/ { :k ; n ; // b k ; N ; N ; N ; d }' input_file

Używa pętli, która drukuje bieżącą linię i odczytuje następną (n), jednocześnie dopasowując wyrażenie regularne (puste wyrażenie regularne // przywołuje ostatnią ocenianą, tj. /^this:/, i polecenie b k wraca do etykiety k przy dopasowaniu). Następnie możesz dołączyć kolejne 3 linie i usunąć całą przestrzeń wzoru, tak jak to zrobiłeś.

Inną możliwością, bardziej zwięzłą, może być użycie GNU sed.

sed '/^this:/ b ; /^/,$ { //,+3 d }' input_file

Ten drukuje każdą linię zaczynającą się od this: (b bez etykiety przechodzi bezpośrednio do następnego cyklu linii po domyślnej akcji drukowania).

W pierwszej linii niezgodnej {{X0} uruchamiane są dwa zagnieżdżone zakresy. Zakres zewnętrzny to „jednorazowy”. Uruchamia się natychmiast z powodu /^/, które pasuje do dowolnej linii, a następnie pozostaje wyzwolone aż do ostatniej linii ($). Zakres wewnętrzny to zakres „przełączany”. Jest również wyzwalany od razu, ponieważ // przywołuje /^/ w tej linii (i tylko w tej linii, stąd jednorazowy zasięg zewnętrzny), a następnie pozostaje wyzwolony przez 3 dodatkowe linie (adres końcowy {{ X5}} jest rozszerzeniem GNU). Następnie /^/ nie jest już oceniana, więc wewnętrzny zakres nie może zostać ponownie uruchomiony, ponieważ // przywołuje /^this:/ (co jest wczesnym skrótem).

0
luciole75w 4 kwiecień 2020, 00:52