Comment puis-je rediriger les lignes correspondantes vers un fichier et les lignes non correspondantes vers un fichier différent?

13

Existe-t-il un script / programme / utilitaire déjà disponible pour l'exigence suivante de manière optimisée?

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

Réponses:

16

Vous pouvez l'utiliser awkpour cela.

command | awk '{ if (/pattern/) { print > "match" } else { print > "nomatch" } }'
Chris Down
la source
1
Je ne suis pas complètement au courant, awkmais à quel moment évalue- >t- il le ? Si elle est évaluée à chaque fois que le conditionnel s'applique, vous vous retrouvez avec deux fichiers d'une ligne ...
Shadur
1
@Shadur >imprime toutes les sorties dans le fichier, écrasant les fichiers existants. Il n'est pas évalué de manière à ce que toutes les nouvelles lignes écrasent l'ancienne sortie de la même instance de awk. Autrement dit, s'il existe plusieurs correspondances, le fichier "correspondance" contiendra chaque correspondance séparée par OFS. La différence entre >et >>existe dans le traitement des fichiers existants.
Chris Down
10

Voici un sedexemple:
Remarque: la wcommande de sed écrasera un fichier existant à chaque exécution du script, mais uniquement si cette commande d'écriture particulière est déclenchée; d'où lerm

rm -f file-{yes,not}  
sed -ne '/pattern/bY; w file-not' -e 'b; :Y; w file-yes' file
Peter.O
la source
Agréable. Sans branchement:sed -n '/PATTERN/p;//! w file-not' infile >file-yes
don_crissti
6

Vous pouvez ajouter des fichiers dans awk:

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

ou plus court:

awk '{print >>(/pattern/?"matched":"unmatched")}'
Michał Šrajer
la source
Son exemple montre qu'il veut écraser les fichiers s'ils existent, pas les ajouter.
Chris Down