6
votes

Comment puis-je supprimer une chaîne après un caractère spécifique UNIQUEMENT dans une colonne / un champ dans awk ou bash?

J'ai un fichier avec des champs (ou colonnes) délimités par des tabulations comme celui-ci ci-dessous:

a   b   c
1   11  213
2   22  222
3   333 83838

Je voudrais tout supprimer après le ";" sur seulement le deuxième champ.

J'ai essayé avec

a   b   c
1   11
2   22  222
3   333

mais cela ne semble pas fonctionner. J'ai aussi essayé avec sed:

 's/;.*//g' abc_table.txt

mais il efface aussi les chaînes du troisième champ:

awk 'BEGIN{FS=OFS="\t"} NR>=1 && sub (/;[*]/,"",$2){print $0}' abc_table.txt

La sortie souhaitée est:

cat abc_table.txt
a   b   c
1   11;qqw  213
2   22  222
3   333;rs2 83838

Si quelqu'un pouvait m'aider, je serais très reconnaissant!


1 commentaires

Vous avez utilisé l'expression rationnelle /;.*/ dans sed mais une expression rationnelle complètement différente /;[*]/ dans awk pour une raison quelconque. Si vous aviez gardé la même expression rationnelle dans awk que dans sed, cela aurait fonctionné.


3 Réponses :


6
votes

Vous devez simplement corriger votre regex.

awk 'BEGIN{FS=OFS="\t"} {sub(/;.*/,"",$2)} 1' Input_file

Dans le cas où vous avez délimité Input_file TAB, essayez:

awk '{sub(/;.*/,"",$2)} 1' Input_file

Problème dans l'expression rationnelle d' OP : regex d' OP ;[*] recherche ; et * (caractère littéral) dans le 2ème champ, c'est pourquoi il n'est PAS capable de tout remplacer après ; dans le 2ème champ. Nous devons simplement donner ;.* qui signifie tout saisir dès la première occurrence de ; jusqu'au dernier du 2e champ, puis remplacez-le par NULL dans le 2e champ.


0 commentaires

3
votes

Une solution alternative utilisant gnu sed :

a   b   c
1   11  213
2   22  222
3   333 83838
sed -E 's/(^[^\t]*\t+[^;]*);[^\t]*/\1/' file


0 commentaires

1
votes

Cela pourrait fonctionner pour vous (GNU sed):

sed 's/[^\t]*/&\n/1;s//&\n/3;s/;[^\t]*\n//g;s/\n//g' file

Ajoutez un marqueur unique, par exemple une nouvelle ligne, à la fin du champ 2.

Retirez tout du premier ; qui n'est pas un onglet vers une nouvelle ligne.

Supprimez la nouvelle ligne le cas échéant.

NB Cette méthode peut être étendue pour les champs sélectifs ou pour tous les champs par exemple même suppression mais pour les premier et troisième champs:

sed 's/[^\t]*/&\n/2;s/;[^\t]*\n//;s/\n//' file


0 commentaires