2009-11-03 24 views
62

Jak mogę utworzyć linie dopasowania pasujące do pewnego wyrażenia, ale zignorować niepasujące linie, zamiast pozwolić im drukować?Czy chcesz, aby sed ignorował niepasujące linie?

Jako prawdziwy przykład, chcę uruchomić scalac (kompilator Scala) na zbiorze plików i odczytać z jego pliku -verbose utworzone pliki .class. scalac -verbose wyprowadza kilka wiadomości, ale interesują nas tylko te w postaci [wrote some-class-name.class]. Co mam aktualnie robi się to (|& to drogę do stderr rury Bash 4.0 do następnego programu):

$ scalac -verbose some-file.scala ... |& sed 's/^\[wrote \(.*\.class\)\]$/\1/' 

To będzie wyodrębnić nazwy pliku z wiadomościami, które są zainteresowani, ale będzie niech wszystkie inne wiadomości przejdą niezmienione! Oczywiście moglibyśmy zrobić zamiast tego:

$ scalac -verbose some-file.scala ... |& grep '^\[wrote .*\.class\]$' | 
    sed 's/^\[wrote \(.*\.class\)\]$/\1/' 

który działa, ale wygląda bardzo podobnie jak dzieje wokół rzeczywistego problemu, który jest jak instruować sed ignorować niedopasowane wiersze z wejścia. Więc jak to robimy?

Odpowiedz

65

Inny sposób zwykły sed:

sed -e 's/.../.../;t;d' 

s/// jest substituion, t bez etykiety warunkowo przeskakuje wszystkich kolejnych poleceń d usuwa linii.

Nie trzeba używać języka Perl lub grep.

(wydanej po sugestii Nicholas Riley)

+3

Na OS X 10.8.2 musiałem oddzielić 'tx' i' d' od znaku nowej linii zamiast średnika, gdy otrzymywałem 'niezdefiniowaną etykietę 'x; d;: x''. – davidchambers

+4

Jeszcze lepiej: 'sed -e 's /.../.../' -e 'tx' -e 'd' -e ': x'' (sugerowane w komentarzu do [podobnego pytania] (http : //stackoverflow.com/a/1252191/312785)). – davidchambers

+1

't' przeniesie się na koniec skryptu, jeśli nie zostanie dostarczona etykieta, więc prostsze: 'sed -e 's /.../.../' -e 't' -e 'd''. –

3

Wykorzystanie Perl:

... |& perl -ne 'print "$1\n" if /^\[wrote (.*\.class)\]$/' 
164

Jeśli nie chcesz drukować linie, które nie pasują do siebie, można użyć kombinacji

  • -n opcją który mówi nie sed do drukowania
  • p flaga, która mówi sed do drukowania, co jest dopasowane

Daje:

sed -n 's/.../.../p' 
+7

ta powinna być przyjęta odpowiedź –

+1

Jedną wadą tego podejścia jest to, jeśli masz kilka wyrażeń, które odpowiadają, wynik zostanie także drukowane wielokrotnie. Na przykład: 'echo foo | sed -n -e 's/foo/bar/p' -e 's/bar/oof/p'' wypisze w osobnych wierszach zarówno 'bar' jak i' oof'. Chociaż odmiany goto-label nie mogą obsłużyć wielu wzorów, ponieważ usunie linię, jeśli pierwszy wzorzec nie pasuje. – Rapsey

Powiązane problemy