Como redirecionar linhas correspondentes para um arquivo e linhas não correspondentes para um arquivo diferente?

13

Existe um script / programa / utilitário já disponível para o seguinte requisito de maneira otimizada?

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

Respostas:

16

Você poderia usar awkpara isso.

command | awk '{ if (/pattern/) { print > "match" } else { print > "nomatch" } }'
Chris Down
fonte
1
Não estou completamente familiarizado, awkmas em que momento ele avalia o >? Se é avaliada cada vez que o condicional aplica-se, você ia acabar com dois arquivos de uma linha ...
Shadur
1
@Shadur >imprime toda a saída no arquivo, substituindo os arquivos existentes. Não é avaliado de tal maneira que resultará em novas linhas substituindo a saída antiga da mesma instância de awk. Ou seja, se houver várias correspondências, o arquivo "correspondência" conterá cada correspondência separada por OFS. A diferença entre >e >>existe no tratamento de arquivos existentes.
Chris Baixo
10

Aqui está um sedexemplo:
Nota: o wcomando sed irá substituir um arquivo existente toda vez que o script for executado, mas apenas se esse comando de gravação específico for acionado; daí orm

rm -f file-{yes,not}  
sed -ne '/pattern/bY; w file-not' -e 'b; :Y; w file-yes' file
Peter.O
fonte
Agradável. Sem ramificação:sed -n '/PATTERN/p;//! w file-not' infile >file-yes
don_crissti 04/04
6

Você pode anexar arquivos no awk:

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

ou mais curto:

awk '{print >>(/pattern/?"matched":"unmatched")}'
Michał Šrajer
fonte
Seu exemplo mostra que ele deseja sobrescrever os arquivos, se eles existirem, não anexar.
Chris Baixo