J'ai un fichier au format suivant:
A 485C72F95C72E15C EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL
Je veux fournir la lettre dans la première colonne en utilisant la valeur de la variable 'lettre' et remplacer la valeur dans la deuxième colonne par une valeur que je fournis dans la variable 'id'. La troisième colonne peut différer ou ne pas correspondre dans tous les cas. Les première et deuxième colonnes ne contiendront jamais d'espaces ni de caractères spéciaux.
J'ai essayé d'utiliser sed
, mais mon sed-fu n'est pas puissant. Je suis venu avec ceci:
letter=A
id=MYNEWIDSTRING
sed "/$letter /s/[^ ]*/$id/2"
La sortie est:
A MYNEWIDSTRING EXTERNAL
B MYNEWIDSTRING SYSTEM
C EC2A63F12A63B76C EXTERNAL
L'identifiant est remplacé sur deux lignes, je suppose que cela est dû à la correspondance de 'A' à la fin de la chaîne d'identifiant d'origine.
Je sais utiliser sed -i
pour éditer le fichier in-situ, mais je ne le fais pas encore, car ma commande est encore un peu louche.
Où est-ce que je me suis trompé ou devrais-je utiliser une méthode différente?
Ancrez-le (^
est le début de la ligne) de sorte que le A
ne corresponde que s'il s'agit du premier caractère:
$ letter=A; id=MYNEWIDSTRING; sed "/^$letter /s/[^ ]*/$id/2" file
A MYNEWIDSTRING EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL
soit dit en passant, si vous voulez passer des variables à sed
mais que vous avez besoin de guillemets serrés, souvenez-vous que vous pouvez activer et désactiver les guillemets tout en ajoutant des guillemets doubles pour les variables - moche mais probablement meilleure pratique en général:
sed '/^'"$letter"' /s/[^ ]*/'"$id"'/2'
Chaque fois que vous avez affaire à des données structurées, j'atteins plutôt awk
ou Perl
plutôt que sed
.
Par exemple
awk -v letter="A" -v id="MYNEWIDSTRING" '$1 == letter {$2=id}1' file
A MYNEWIDSTRING EXTERNAL
B CC32480A3247F84A SYSTEM
C EC2A63F12A63B76C EXTERNAL
ou
Perl -alne '
BEGIN{$letter = shift; $id = shift;}
print join " ", $F[0], $F[0] eq $letter ? $id : $F[1], @F[2..$#F]
' 'A' 'MYNEWIDSTRING' file
Les versions les plus récentes de GNU awk ont un indicateur -i
(--in-place
); dans d'autres, vous devrez utiliser un fichier temporaire explicite; Perl devrait avoir un -i
dans tous les cas.