używam tego
cat foo.txt | sed '/bar/d'
aby usunąć wiersze zawierające ciąg znaków bar
w pliku.
Chciałbym jednak usunąć te linie i linię bezpośrednio po niej . Korzystnie sed
, awk
lub inne narzędzie, które jest dostępne w mingw32.
Jest to rodzaj odwrocie, co mogę dostać grep
się -A
i -B
zanim do drukowania pasujących wierszy, jak również linie / po dopasowanej linii.
Czy jest jakiś prosty sposób na osiągnięcie tego?
text-processing
sed
awk
replace
jakub.g
źródło
źródło
Odpowiedzi:
Jeśli masz GNU sed (tak niewbudowany Linux lub Cygwin):
Jeśli masz
bar
dwa kolejne wiersze, spowoduje to usunięcie drugiego wiersza bez jego analizy. Na przykład, jeśli masz plik 3-liniowybar
/bar
/foo
,foo
linia pozostanie.źródło
bar
s, więc ten jest bardzo łatwy do zapamiętania.sed '/bar/d'
jeśli chcesz po prostu „Usuń wiersz zawierający określony ciąg”, a nie następny.sed '/math/q'
sed '/bar/d'
Jeśli
bar
może wystąpić na kolejnych liniach, możesz:które można dostosować, aby usunąć więcej niż 2 linie, zmieniając 2 powyżej z liczbą linii do usunięcia, w tym pasującą.
Jeśli nie, łatwo to zrobić
sed
za pomocą rozwiązania @MichaelRollins lub:źródło
/bar/
z/bar|baz|whatever/
. Wsed
tej składni wydaje się nie działać.sed
o użycie „rozszerzonych” wyrażeń regularnych. Więcej informacji tutaj: gnu.org/software/sed/manual/html_node/… . Należy pamiętać, że dotyczy togrep
również. Oto mój własny przykład praca:echo $'0a\n1b\n2c' | sed '/0a\|1b/d'
.Nie jestem biegły w sed, ale łatwo to zrobić w awk:
Skrypt awk brzmi: dla linii zawierającej pasek, pobierz następną linię (getline), a następnie pomiń wszystkie dalsze przetwarzanie (następne). Wzór 1 na końcu drukuje pozostałe linie.
Aktualizacja
Jak wskazano w komentarzu, powyższe rozwiązanie nie działało z kolejnymi
bar
. Oto poprawione rozwiązanie, które uwzględnia to:Teraz czytamy, aby pominąć wszystkie linie / bar /.
źródło
grep -A
100%, musisz równieżbar
poprawnie obsłużyć dowolną liczbę kolejnych linii (usuwając cały blok i 1 linię po).Będziesz chciał skorzystać z możliwości skryptów sed, aby to osiągnąć.
Przykładowe dane:
Polecenie „N” dołącza następny wiersz danych wejściowych do obszaru wzorów. W połączeniu z linią z dopasowania wzorca (/ bar /) będą to linie, które chcesz usunąć. Następnie możesz normalnie usunąć polecenie „d”.
źródło
sed -e '/bar/{N;d}' sample1.txt
Jeśli jakikolwiek wiersz bezpośrednio po dopasowaniu zostanie usunięty, wówczas twój
sed
program będzie musiał rozważyć kolejne dopasowania. Innymi słowy, jeśli usuniesz linię po dopasowaniu, które również pasuje, prawdopodobnie prawdopodobnie powinieneś również usunąć linię po tym.Jest zaimplementowany po prostu - ale trzeba trochę popatrzeć.
Działa poprzez zamianę przestrzeni wstrzymania i wzorów dla każdej wczytywanej linii - dzięki czemu za każdym razem można porównać ostatnią linię z bieżącą. Tak więc, gdy
sed
czyta linię, wymienia zawartość swoich buforów - a poprzednia linia jest wówczas zawartością bufora edycji, podczas gdy bieżąca linia jest umieszczana w miejscu wstrzymania.sed
Sprawdza więc poprzedni wiersz pod kątem dopasowania domatch
, a jeśli go!
nie znaleziono, uruchamiane są dwa wyrażenia w{
funkcji}
.sed
wolag
i miejsca przechowywania przez nadpisanie przestrzeń Pattern - co oznacza, że bieżąca linia jest wówczas w obu luku i wzór przestrzeni - i wtedy będzie//
to sprawdzić na mecz do jej ostatnio skompilowanego wyrażenia regularnego -match
- a jeśli to niematch
ona jestp
zabarwionyOznacza to, że linia jest drukowana tylko wtedy, gdy nie, a linia poprzednio poprzednia nie . Zapobiega także wszelkim niepotrzebnym zamianom sekwencji es.
match
match
match
Jeśli chcesz wersję, która może upuszczać dowolną liczbę wierszy pojawiających się po
match
niej, wymaga trochę więcej pracy:... zamień 5 na liczbę linii (w tym dopasowaną linię) , którą chcesz usunąć ...
źródło