Disons que j'ai un fichier texte comme:
R1 12 324 3453 36 457 4 7 8
R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242
Je veux utiliser awk
pour traiter ces lignes différemment, comme
awk '/R1/ { print "=>" $0} /R2/ { print "*" $0} '
et je veux également imprimer toutes les autres lignes telles quelles (sans faire de doublons des lignes que j'ai déjà traitées), en gros j'ai besoin d'un /ELSE/ { print $0}
à la fin de ma awk
ligne.
Existe-t-il une telle chose?
awk
met en œuvre les suspects habituels en matière de conditionnels. C'est une bonne idée d'utiliserprintf
au lieu deprint
pour le travail que vous souhaitez faire en match.la source
if-then-else
.next
est un outil important dans la programmation awk.printf
ici. Son seul avantage (sauf si vous faites un formatage plus sophistiqué que la concaténation) est qu'il n'ajoute pas de nouvelle ligne, ce qui n'est pas pertinent ici.print
n'a qu'à sortir$0
alors qu'ilprintf
doit analyser une chaîne de format.Chris Down a déjà montré comment obtenir un autre pour les expressions rationnelles en utilisant une instruction explicite «if» dans un bloc. Vous pouvez également obtenir le même effet d'une autre manière, bien que sa solution soit probablement meilleure.
La première consiste à écrire une troisième expression régulière qui ne correspondra qu'au texte qui ne correspond pas aux autres, dans votre cas, cela ressemblerait à ceci:
Remarque, cela utilise des expressions rationnelles ancrées - le ^ au début des expressions régulières ne correspondra qu'au début d'une ligne - vos modèles originaux ne l'ont pas fait, ce qui ralentit légèrement la correspondance car il vérifiera tous les caractères sur une ligne plutôt que sauter jusqu'à la ligne suivante. Le troisième cas ("else") correspondra à une ligne qui commence par un caractère qui n'est pas 'R' ([^ R]) ou qui commence par un 'R' suivi d'un caractère qui n'est pas un '1' ou ' 2 '(R [^ 12]). Les deux significations différentes de ^ sont quelque peu déroutantes, mais cette erreur a été commise il y a longtemps et ne sera pas modifiée de si tôt.
Pour utiliser des expressions rationnelles complémentaires, elles doivent vraiment être ancrées, sinon le [^ R] correspondrait par exemple au 1 qui le suit. Pour les regexps très simples comme vous, cette approche peut être utile, mais à mesure que les regexps deviennent plus complexes, cette approche deviendra ingérable. Au lieu de cela, vous pouvez utiliser des variables d'état pour chaque ligne, comme ceci:
Cela met à zéro géré pour chaque nouvelle ligne, puis à 1 si elle correspond à l'un des deux regexps, et enfin, si elle est toujours nulle, exécute l'impression $ 0.
la source
rfile
n'est que 10000 lignes de l'ensemble de données du questionneur répétées.if (!handled)
Beurk! Utiliseznext
pour arrêter d'envisager d'autres actions.if (!handled)
. Les solutions générales, flexibles et réutilisables sont bonnes. Que se passe-t-il si la prochaine personne qui a cette question souhaite faire plus de traitement après l'impression? Les réponses avecnext
ne soutiennent pas cela.