Replacer texte sur la première occurrence du fichier

Résolu/Fermé
Nyser - Modifié le 12 janv. 2023 à 15:15
mamiemando Messages postés 33410 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 2 décembre 2024 - 17 janv. 2023 à 16:17

Bonjour,

Je cherche a écrire un script qui va modifier des informations sur des fichiers générés automatiquement. Mon fichier ressemble initialement à ça  :

toto 1111
tata 1234
toto 1111

J'aimerais changer uniquement le 1er "toto 1111" en "toto 1269" avec la commande sed
J'arrive a le changer les deux toto avec l'indice de substitution s mais même sans mettre le g pour l'appliquer à tout le fichier, il me modifie les deux. 

Merci d'avance pour vos réponses.  

A voir également:

5 réponses

xHaMaz Messages postés 108 Date d'inscription mardi 3 janvier 2023 Statut Membre Dernière intervention 23 avril 2023 14
11 janv. 2023 à 15:07

Bonjour

sed '1s/^toto 1111$/toto 1269/' inputfile.txt > outputfile.txt

Essaye ça

1
dubcek Messages postés 18755 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 14 novembre 2024 5 621
Modifié le 12 janv. 2023 à 11:00

hello

$ awk '/toto/ && !n++ {$2=1269} {print $0}' fichier

toto 1269

tata 1234

toto 1111

$ sed '0,/toto/{s/1111/1269/}'  fichier

toto 1269

tata 1234

toto 1111
$ 

1

Ca n'a pas marché, ça ne modifie rien

Mais merci pour la tentative et la réactivité ;)

0
mamiemando Messages postés 33410 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 2 décembre 2024 7 808
Modifié le 12 janv. 2023 à 15:33

La commande marche mais le résultat est généré dans un autre fichier (outputfile.txt). Il faut de plus veiller à ce que la ligne soit exactement conforme (pas d'espace en plus). La commande cat -A permet de vérifier en affichant $ en fin de ligne.

Ensuite, la commande fournie par xHaMaz génère le résultat dans un autre fichier. Si tu tu veux que la substitution soit faite en place dans le fichier d'entrée (disons input.txt), il faut utiliser l'option -i.

(mando@silk) (~) $ cat -A input.txt
toto 1111$
tata 1234$
toto 1111$

(mando@silk) (~) $ sed -i '1s/^toto 1111$/toto 1269/' input.txt

(mando@silk) (~) $ cat -A input.txt
toto 1269$
tata 1234$
toto 1111$

Bonne chance

1
Nyser Messages postés 4 Date d'inscription mercredi 11 janvier 2023 Statut Membre Dernière intervention 31 mars 2023 > mamiemando Messages postés 33410 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 2 décembre 2024
13 janv. 2023 à 09:25

Waow ! super, merci pour ces explications ! 

0
Nyser Messages postés 4 Date d'inscription mercredi 11 janvier 2023 Statut Membre Dernière intervention 31 mars 2023
12 janv. 2023 à 11:34

Merci, en effet ça fonctionne ! j'utilise la commande sed. 

Pourrais-tu m'expliquer à quoi sert le 0 ? 

Merci d'avance !

0
mamiemando Messages postés 33410 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 2 décembre 2024 7 808
Modifié le 12 janv. 2023 à 15:54

La solution #3 proposée par dubcek basée sur sed repose sur la notion de range specifier (voir ici). Expliquons cette notion sur ton exemple :

  • Si tu connais le numéro de ligne (ici 1) sur lequel la modification doit opérer , tu peux écrire :
    sed '1,1s/^toto 1111$/toto 1269/' input.txt
    ou de manière plus laxiste : 
    sed '1,1s/1111/1269/' input.txt
    ... ce qui signifie :
    • sur la plage de ligne allant de 1 à 1 incluses,
    • applique la substitution qui remplace la première occurrence de 1111 par 1269).
  • La commande de dubcek #3 est plus générale, car elle n'a pas d'a priori sur la ligne dans laquelle figure la première occurrence à substituer :
    sed '0,/toto/{s/1111/1269/}' input.txt
    ... ce qui signifie :
    • cherche la première ligne qui est validée par l'expression rationnelle "toto" (donc la première ligne qui contient toto) : c'est une syntaxe spécifique, voir ici
    • puis, applique la substitution qui remplace la première occurrence de 1111 par 1269
    • si tu remplaces le 0 par un entier n strictement positif, la recherche de la ligne se fait pour toutes les lignes validées à partir de la ligne n incluse

Bonne chance

1
Nyser Messages postés 4 Date d'inscription mercredi 11 janvier 2023 Statut Membre Dernière intervention 31 mars 2023 > mamiemando Messages postés 33410 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 2 décembre 2024
Modifié le 16 janv. 2023 à 16:42

Et sais tu s'il est possible de remplacer le début de la recherche (0) dans l'exemple par une adresse ? 

Je m'explique, à la place cette commande :

sed '0,/toto/{s/1111/1269/}' input.txt

j'aimerai modifier le 0 mais non pas par un entier mais par une phrase. 

Par exemple :

toto 1111

tata 1234

toto 1111

titi 4321

tata 6789

toto 1111

j'aimerai modifier le dernier toto uniquement et a partir de tata 6789 par exemple. J'imaginai un truc comme ça : 

sed 'tata 6789,/toto/{s/1111/1269/}' input.txt

Mais ça ne marche pas

0
mamiemando Messages postés 33410 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 2 décembre 2024 7 808 > Nyser Messages postés 4 Date d'inscription mercredi 11 janvier 2023 Statut Membre Dernière intervention 31 mars 2023
Modifié le 17 janv. 2023 à 16:29

Je ne sais pas si tu peux faire comme tu essayes de faire, mais c'est peut-être faisable.

Personnellement, je pense qu'il devient d'écrire un script shell, dans lequel tu lances une première commande trouve le numéro de ligne de la dernière occurrence de toto.

j=`grep -n "^toto" fichier.txt | tail -n 1 | cut -d":" -f 1`
echo "$j"

... et une autre le numéro de ligne qui contient "tata 6789" :

i=`grep -n "^tata 6789$" fichier | head -n 1 | cut -d":" -f 1`
echo "$i"

Il faut ensuite contrôler que i et j sont bien définis (donc que les deux motifs cherchés on été trouvés) et comparer i et j (i < j). Dans ce cas, un remplacement est possible, et $j te donne le numéro de ligne où opérer, tu peux utiliser sed et un range specifier basé sur $j. 

if [[ -z "$i" && -z "$j" && "$i" -lt "$j" ]]
then
    eval "sed '${j},${j}s/^toto/toto 5678/' fichier.txt"
fi

Bon je ne te cache pas que moi je ferais tout ça en python plutôt qu'en shell mais ça c'est affaire de goût :-D

1

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
dubcek Messages postés 18755 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 14 novembre 2024 5 621
Modifié le 17 janv. 2023 à 11:46
$ sed '/tata 6789/,/toto/s/1111/1269/' input.txt
toto 1111

tata 1234

toto 1111

titi 4321

tata 6789

toto 1269
0