2009-09-22 9 views
0

J'ai obtenu un document que les champs sont séparés par un deux-points (:) où j'ai besoin de changer le deuxième champ de temps en temps. Le document ressemble à ceci:sed: Rechercher et remplacer colonne variable

name1:UhX.PPFW7$YhPMH0BISY:23490:::::: 
name2:1./0oV$GEs6WJpE$LHXhy:19239:0:29388:2::29302: 
... 

Le deuxième champ du fichier va changer de temps en temps et peut contenir un ou deux caractères d'expression régulière (de $.) Et une barre oblique.

Je voudrais remplacer uniquement le deuxième champ car les données qui le suivent peuvent être différentes dans le futur. Si je fais:

sed -e "s~^name2:.*:~name2:aTest\$repl.ace:~g" tst 

Le texte à droite de la deuxième colonne est perdue:

name2:aTest$repl.ace: 

(à savoir le '19239: 0: 29388: 2 :: 29302:'). Est-il possible que sed puisse remplacer une colonne variable et préserver le reste de la ligne? Ou, peut-être, y a-t-il un meilleur programme pour le faire?

Répondre

0

La façon la plus simple est de changer le. * dans votre expression rationnelle pour correspondre uniquement à ce qui peut apparaître dans le second champ, par exemple:

sed -e "s~^name2:[^:]*:~name2:aTest\$repl.ace:~g" tst 

([^:] * == quoi que ce soit qui ne contient pas deux points), ou:

sed -e "s~^name2:[$./0-9a-zA-Z]*:~name2:aTest\$repl.ace:~g" tst 

([bla] * == un certain nombre de caractères listés)

+0

Hé c'est génial. Je me demandais si c'était possible dans sed. J'ai pensé que je pourrais regarder une commande plus compliquée. Appréciez le pourboire, Anthony. –

0

Sed n'est probablement pas le meilleur outil pour cela, car si ne sait pas vraiment sur les champs. Envisager awk (qui a construit dans le concept de champs) à la place:

$ awk -F : 'NF>=2{split($0,a,":");a[2]="new sting";printf(a[1]);for(i=2;i<=NF;i++){printf":%s",a[i]};printf("\n");}' <input file> 

ou formaté pour la lisibilité:

awk -F : 'NF>=2 { 
        split($0,a,":"); 
        a[2]="new sting"; 
        printf(a[1]); 
        for(i=2;i<=NF;i++){ 
        printf":%s",a[i] 
        }; 
        printf("\n"); 
       }' <input file> 

Pour la généralité, vous voudrez peut-être remplacer le ":" avec FS. Il est également intéressant de regarder t his join function qui rendrait l'implémentation plus propre si vous écriviez un script plutôt que de l'exécuter sur la ligne de commande.

Cette implémentation suppose que vous souhaitez remplacer tous les champs. Si yu besoin de ne sélectionner que quelques-unes des lignes de remplacement, changer le modèle à

$2=="string to match" 

ou

$2~/regex to match/ 
+0

heh, awk est un peu sur ma tête à l'époque mais ça marche. Je vous remercie. –

0

Essayez ceci:

perl -pe 's~^name2:.*?:~name2:aTest\$repl.ace:~g' test 
+0

Commençant à aimer perl - toutes les syntaxes qu'il utilise (que j'ai vu) sont faciles à retenir la syntaxe. Merci pour l'ennuikiller de pointe. –

Questions connexes