remplacer les données après le dernier délimiteur de chaque ligne en utilisant sed ou awk

J’ai un fichier texte A.txt , toutes les lignes dans lesquelles le même nombre de champs est séparé par un tuyau | délimiteur. J’ai besoin de remplacer , avec | pour les données après le dernier délimiteur de chaque ligne.

Exemple:

 1,2|3,4|5|6,7,8 1,8|4|6,5,3|4,5 

Sortie souhaitée, (remplacez uniquement , après le dernier délimiteur):

 1,2|3,4|5|6|7|8 1,8|4|6,5,3|4|5 

Comment y parvenir en utilisant sed ou awk ?

Avec awk :

 awk 'BEGIN{FS=OFS="|"} gsub(",", "|", $NF)' 
  • BEGIN{FS=OFS="|"} définit le séparateur de champ d’entrée et de sortie comme littéral |

  • gsub(",", "|", $NF) remplace tout ( gsub() ) , s par | dans le dernier champ ( $NF )

Exemple:

 $ awk 'BEGIN{FS=OFS="|"} gsub(",", "|", $NF)' <<<'1,2|3,4|5|6,7,8' 1,2|3,4|5|6|7|8 $ awk 'BEGIN{FS=OFS="|"} gsub(",", "|", $NF)' <<<'1,8|4|6,5,3|4,5' 1,8|4|6,5,3|4|5 
 $ cat ip.txt 1,2|3,4|5|6,7,8 1,8|4|6,5,3|4,5 

avec sed

 $ sed -E ':as/^(.*\|[^,]+),([^|]+)$/\1|\2/g; ta' ip.txt 1,2|3,4|5|6|7|8 1,8|4|6,5,3|4|5 
  • :a et ta pour boucler la commande sed jusqu’à ce qu’une correspondance soit trouvée
  • ^(.*\|[^,]+) du début de la ligne à | suivi de non caractères. * et + essaieront de correspondre autant que possible
  • , correspond à une virgule
  • ([^|]+)$ après la virgule, il ne devrait y en avoir aucun | caractère jusqu’à la fin de la ligne

avec perl

 $ perl -F'\|' -lane '$F[-1] =~ tr/,/|/; print join "|",@F' ip.txt 1,2|3,4|5|6|7|8 1,8|4|6,5,3|4|5 
  • -F'\|' fractionner la ligne d’entrée sur | et enregistrer dans le tableau @F
  • $F[-1] =~ tr/,/|/; pour le dernier élément du tableau, remplacez tout , avec |
  • print join "|",@F @F tableau @F modifié avec | comme séparateur

Et pour de la magie regex:

 $ perl -pe 's/.*\|(*SKIP)(*F)|,/|/g' ip.txt 1,2|3,4|5|6|7|8 1,8|4|6,5,3|4|5 
  • .*\|(*SKIP)(*F) ignore le motif jusqu’à la dernière |
  • puis remplacez tout , avec |