Remplacement de plusieurs occurrences d’un mot par sed dans unix

En unix, j’ai l’obligation de remplacer une occurrence de mot par un espace. Mon fichier ressemble à quelque chose comme ci-dessous. J’ai besoin de remplacer | NA | avec un espace

Format de fichier

1234|NA|NA|abcd|xyz 2345|NA|NA|NA|lmn 456|NA|abcd|xya|ggh 

Production attendue

 1234| | |abcd|xyz 2345| | | |lmn 456| |abcd|xya|ggh 

J’utilise la commande suivante mais elle ne remplace que la toute première occurrence

 sed 's/|NA|| |/g' 

Alors que le modificateur g effectue des remplacements “globaux”, les remplacements doivent être sans chevauchement. Lorsque des remplacements sont nécessaires, il faut boucler:

 $ sed ':a; s/|NA|/| |/g; ta' file.txt 1234| | |abcd|xyz 2345| | | |lmn 456| |abcd|xya|ggh 

Ce qui précède a été testé sur GNU sed. Pour BSD (OSX) sed (astuce: Jonathan Leffler), le libellé a doit apparaître qu’à la fin d’une chaîne de commande:

 sed -e ':a' -e ' s/|NA|/| |/g; ta' file.txt 

Comment ça marche

  • :a crée une étiquette a .

  • s/|NA|/| |/g s/|NA|/| |/g effectue la substitution souhaitée, mais uniquement pour les instances sans chevauchement de |NA| .

  • ta dit à sed de sauter à l’étiquette si la commande de substitution précédente a entraîné des modifications à la ligne. De cette manière, la commande de substitution est répétée autant de fois que nécessaire pour remplacer chaque occurrence de |NA| .

Utilisez simplement awk pour plus de clarté, de simplicité, de portabilité, d’extensibilité, etc.

 $ awk '{while(gsub(/\|NA\|/,"| |"));}1' file 1234| | |abcd|xyz 2345| | | |lmn 456| |abcd|xya|ggh 

La première fois dans la boucle, le gsub () remplace toutes les occurrences impaires de l’expression rationnelle et la deuxième fois qu’il est remplacé. Il fonctionnera tel quel avec n’importe quel awk sur n’importe quel système UNIX.

N’a pas essayé complètement d’échapper à la barre verticale. Alors fait une tentative sans avoir la barre verticale impliquée et cela a fonctionné! Il manquait aussi que le remplacement ne soit qu’un espace, maintenant corrigé. De cette façon, le champ est facilement extensible en ajoutant de l’espace.

  awk '{gsub(/NA/," ")}1' file 1234| | |abcd|xyz 2345| | | |lmn 456| |abcd|xya|ggh