Fichier d'origine
claudio
antonio
claudio
michele
Je souhaite modifier uniquement la première occurrence de "claudio" par "claudia" afin que le résultat du fichier
claudia
antonio
claudio
michele
j'ai essayé
sed -e '1,/claudio/s/claudio/claudia/' nomi
Mais effectuez une substitution globale. Pourquoi?
info sed
: (0,/REGEXP/
: Un numéro de ligne de 0 peut être utilisé dans une spécification d'adresse comme0,/REGEXP/
poursed
essayer de faire correspondre REGEXP dans la première ligne d'entrée également. En d'autres termes,0,/REGEXP/
est similaire à1,/REGEXP/
, sauf que si ADDR2 correspond à la toute première ligne d'entrée, le formulaire 0, / REGEXP / le considérera comme mettant fin à la plage, tandis que le formulaire 1, / REGEXP / correspondra au début de sa plage et donc étendra la plage jusqu'à la deuxième occurrence de l'expression régulière)awk '/claudio/ && !ok { sub(/claudio/,"claudia"); ok=1 } 1' nomi
devrait faireRéponses:
Si vous utilisez GNU
sed
, essayez:sed
ne démarre pas la vérification de la regex qui met fin à une plage jusqu'à après la ligne qui commence cette plage.De
man sed
(page de manuel POSIX, c'est moi qui souligne):En utilisant
awk
Les plages de
awk
travail fonctionnent plus que vous attendiez:Explication:
NR==1,/claudio/
Il s'agit d'une plage qui commence par la ligne 1 et se termine par la première occurrence de
claudio
.sub(/claudio/, "claudia")
Pendant que nous sommes dans la plage, cette commande de substitution est exécutée.
1
Le raccourci cryptique de cet awk pour imprimer la ligne.
la source
sed
cependant GNU .awk '!r && /claudio/ {sub(/claudio/,"claudia"); r=1} 1'
awk !x{x=sub(/claudio/,"claudia")}1
0,/claudio/
Voici 2 autres efforts de programmation avec sed: ils lisent tous les deux le fichier entier dans une seule chaîne, puis la recherche ne remplacera que le premier.
Avec commentaire:
la source
Une nouvelle version de GNU
sed
prend en charge l'-z
option.Vous pouvez utiliser cette option lorsque vous souhaitez
sed
travailler sur différentes lignes.résultats
la source
Vous pouvez utiliser
awk
un indicateur pour savoir si le remplacement a déjà été effectué. Sinon, continuez:la source
C'est vraiment très facile si vous configurez juste un peu de retard - il n'est pas nécessaire d'aller chercher des extensions peu fiables:
Cela reporte simplement la première ligne à la deuxième et la deuxième à la troisième et etc.
Il imprime:
la source
Et encore une option
L'avantage est qu'il utilise des guillemets doubles, vous pouvez donc utiliser des variables à l'intérieur, par exemple.
la source
Cela peut également être fait sans l'espace d'attente et sans concaténer toutes les lignes dans l'espace de motif:
Explication: Nous essayons de trouver "claudio" et si nous le faisons, nous sautons dans la petite boucle de chargement d'impression entre
:x
etbx
. Sinon, nous imprimons et redémarrons le script avec la ligne suivante.la source
la source
Résumé
Syntaxe GNU:
Ou même (pour n'utiliser qu'une seule fois le mot à remplacer:
Ou, dans la syntaxe POSIX:
fonctionne sur n'importe quel sed, traite uniquement autant de lignes que nécessaire pour trouver la première
claudio
, fonctionne même s'ilclaudio
est dans la première ligne et est plus court car il n'utilise qu'une seule chaîne d'expression régulière.Détail
Pour modifier une seule ligne, vous devez sélectionner une seule ligne.
L'utilisation d'un
1,/claudio/
(à partir de votre question) sélectionne:claudio
.Pour sélectionner une ligne qui contient
claudio
, utilisez:Et pour ne sélectionner que le premier
claudio
du fichier, utilisez:Ensuite, vous pouvez effectuer une substitution uniquement sur cette ligne:
Ce qui ne changera que le premier occurrence de la correspondance d'expression régulière sur la ligne, même s'il peut y en avoir plusieurs, sur la première ligne qui correspond à l'expression régulière.
Bien sûr, l'
/claudio/
expression rationnelle pourrait être simplifiée pour:Et puis, la seule chose qui manque est d'imprimer toutes les autres lignes non modifiées:
la source