Wie kann ich übereinstimmende Zeilen in eine Datei und nicht übereinstimmende Zeilen in eine andere Datei umleiten?

13

Gibt es bereits ein Skript / Programm / Dienstprogramm für die folgenden Anforderungen auf optimierte Weise?

someCommand |
   tee >(grep "pattern" > LinesWhichMatch) |
   grep -v "pattern" > LinesWhichDoesNotMatch
balki
quelle

Antworten:

16

Sie könnten dafür verwenden awk.

command | awk '{ if (/pattern/) { print > "match" } else { print > "nomatch" } }'
Chris Down
quelle
1
Ich bin nicht ganz vertraut mit, awkaber an welchem ​​Punkt wertet es das aus >? Wenn es jedes Mal ausgewertet wird, wenn die Bedingung zutrifft, erhalten Sie zwei einzeilige Dateien ...
Shadur
1
@Shadur >druckt alle Ausgaben in die Datei und überschreibt vorhandene Dateien. Es wird nicht so ausgewertet, dass neue Zeilen alte Ausgaben derselben Instanz von überschreiben awk. Das heißt, wenn es mehrere Übereinstimmungen gibt, enthält die Datei "Übereinstimmung" jede Übereinstimmung, die durch getrennt ist OFS. Der Unterschied zwischen >und >>besteht in der Behandlung vorhandener Dateien.
Chris Down
10

Hier ein sedBeispiel:
Hinweis: Der wBefehl sed überschreibt bei jeder Ausführung des Skripts eine vorhandene Datei, jedoch nur, wenn dieser bestimmte Schreibbefehl ausgelöst wird. daher dierm

rm -f file-{yes,not}  
sed -ne '/pattern/bY; w file-not' -e 'b; :Y; w file-yes' file
Peter.O
quelle
Nett. Ohne Verzweigung:sed -n '/PATTERN/p;//! w file-not' infile >file-yes
don_crissti
6

Sie können Dateien in awk anhängen:

awk '{if (/pattern/) print >>"matched"; else print >>"unmatched"; }

oder kürzer:

awk '{print >>(/pattern/?"matched":"unmatched")}'
Michał Šrajer
quelle
Sein Beispiel zeigt, dass er die Dateien überschreiben möchte, wenn sie existieren, nicht anhängen.
Chris Down