Rechercher - remplacer avec confirmation
Fermé
Fred
-
13 mai 2019 à 01:11
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 - 14 mai 2019 à 21:17
zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 - 14 mai 2019 à 21:17
A voir également:
- Rechercher - remplacer avec confirmation
- Rechercher ou entrer l'adresse - Guide
- Rechercher et remplacer word - Guide
- Adresse IP locale : comment la trouver facilement - Guide
- Confirmation de lecture whatsapp - Guide
- Remplacer disque dur par ssd - Guide
3 réponses
UnGnU
Messages postés
1158
Date d'inscription
lundi 2 mai 2016
Statut
Contributeur
Dernière intervention
22 décembre 2020
157
13 mai 2019 à 08:24
13 mai 2019 à 08:24
Salut,
Je n'ai pas testé en récursif, ni avec plusieurs remplacements dans le même fichier, mais l'idée est là, à toi d'adapter à ton cas :
Liste des fichiers :
Contenu de chaque fichier :
L'exécution de la ligne de commande avec demande :
Résultat avec remplacement sur fichier 2 et 5 :
Je n'ai pas testé en récursif, ni avec plusieurs remplacements dans le même fichier, mais l'idée est là, à toi d'adapter à ton cas :
Liste des fichiers :
$ tree
.
├── fich1
├── fich2
├── fich3
├── fich4
└── fich5
0 directories, 5 files
Contenu de chaque fichier :
$ more f*
::::::::::::::
fich1
::::::::::::::
motif
::::::::::::::
fich2
::::::::::::::
motif
::::::::::::::
fich3
::::::::::::::
motif
::::::::::::::
fich4
::::::::::::::
motif
::::::::::::::
fich5
::::::::::::::
motif
L'exécution de la ligne de commande avec demande :
$ find . -type f -exec bash -c 'grep -Hn "m" ${1};read -p "Remplacer ?" rep;if [ "${rep}" == o ];then sed -i "s/motif/AAA/" ${1};fi' _ {} \;
./fich5:1:motif
Remplacer ?o
./fich4:1:motif
Remplacer ?n
./fich3:1:motif
Remplacer ?n
./fich2:1:motif
Remplacer ?o
./fich1:1:motif
Remplacer ?n
Résultat avec remplacement sur fichier 2 et 5 :
$ more f*
::::::::::::::
fich1
::::::::::::::
motif
::::::::::::::
fich2
::::::::::::::
AAA
::::::::::::::
fich3
::::::::::::::
motif
::::::::::::::
fich4
::::::::::::::
motif
::::::::::::::
fich5
::::::::::::::
AAA
Merci de ton aide !
Bon après c'est un peu du chinois la syntaxe pour moi...
Quand il ne trouve pas le contenu "motif" dans le fichier, il pose tout de même la question ;((
Bon après c'est un peu du chinois la syntaxe pour moi...
Quand il ne trouve pas le contenu "motif" dans le fichier, il pose tout de même la question ;((
Remplacer ?n
Remplacer ?n
Remplacer ?n
Remplacer ?n
Remplacer ?n
Voici ce que je vais finalement utiliser (merci Bruno !)
# sauvegarder la valeur du séparateur (pour la boucle for), en principe c'est un espace
IFS_BAK="$IFS"
# définir une autre valeur de séparateur : le retour à la ligne
IFS=$( echo -e "\n" )
# boucle sur tous les fichiers trouvés récursivement à partir du répertoire courant
for F in $( find ./ -type f )
do
# faire un test pour savoir si le fichier contient la chaine recherchée
TEST=$( grep 'monancienneadresse\.gmail' "$F" )
# si le test est positif
if [ "$TEST" != "" ]
then
# question
read -p "Remplacer dans $F ?" REPONSE
# si la réponse est o, faire le remplacement sur le fichier (attention, avec -i ça le fait!!!)
[ "$REPONSE" == "o" ] && sed -i 's/monancienneadresse\.gmail/manouvelle\.fr/g' "$F"
fi
done
# rétablir le séparateur par défaut
FS="$IFS_BAK"
lEprofSonDkon
Messages postés
211
Date d'inscription
jeudi 13 décembre 2018
Statut
Membre
Dernière intervention
8 octobre 2022
13
13 mai 2019 à 19:53
13 mai 2019 à 19:53
il ne faut pas faire ça : si un nom de fichier peut contenir un espace, il peut aussi contenir un alinéa.
parce qu'un nom de fichier ne peut jamais contenir de caractère NULL.
et puis
find ./ -type f -print0 | while IFS= read -d ''; do echo ">$REPLY<"; done
parce qu'un nom de fichier ne peut jamais contenir de caractère NULL.
et puis
if grep ...; then...; fi
boxR
Messages postés
4
Date d'inscription
mardi 14 mai 2019
Statut
Membre
Dernière intervention
14 mai 2019
Modifié le 14 mai 2019 à 13:28
Modifié le 14 mai 2019 à 13:28
On pourrait aussi bien l'écrire :
Sauf qu'avec ce type de solution, on ne peut pas poser de question à l'utilisateur dans la boucle, ça ne marche pas :
D'où l'idée du
Après, tu as déjà vu un saut de ligne dans un nom de fichier ?
find ./ -type f | while read F; do echo "$F"; done
Sauf qu'avec ce type de solution, on ne peut pas poser de question à l'utilisateur dans la boucle, ça ne marche pas :
find ./ -type f | while read F; do echo "$F"; read -p "Votre réponse : " REPONSE; ... ; done
D'où l'idée du
force qui nécessite la redéfinition de l'IFS.
Après, tu as déjà vu un saut de ligne dans un nom de fichier ?
lEprofSonDkon
Messages postés
211
Date d'inscription
jeudi 13 décembre 2018
Statut
Membre
Dernière intervention
8 octobre 2022
13
>
boxR
Messages postés
4
Date d'inscription
mardi 14 mai 2019
Statut
Membre
Dernière intervention
14 mai 2019
14 mai 2019 à 13:38
14 mai 2019 à 13:38
ben, oui. c'est pourquoi j'alerte.
et c'est pour ça qu'existe cette option (
on peut créer des variables dans un pipe, il faut mettre tout ce qui suit la barre verticale entre accolades :
en shell POSIX :
ou en bash :
en bash, dans un script, on peut conserver le pipe, et y créer des variables réutilisables en dehors, en positionnant l'option lastpipe avec shopt.
et c'est pour ça qu'existe cette option (
-print0), et son pendant dans d'autres programmes (
xargs -0,
sort -z...).
on peut créer des variables dans un pipe, il faut mettre tout ce qui suit la barre verticale entre accolades :
en shell POSIX :
commande | { while... var=blabla; done; echo "$var";}
ou en bash :
while... var="bibi"; done < <(commande)
en bash, dans un script, on peut conserver le pipe, et y créer des variables réutilisables en dehors, en positionnant l'option lastpipe avec shopt.
boxR
Messages postés
4
Date d'inscription
mardi 14 mai 2019
Statut
Membre
Dernière intervention
14 mai 2019
14 mai 2019 à 14:40
14 mai 2019 à 14:40
Admettons pour le retour à la ligne, même si ça me paraît exotique.
Le souci n'est pas de définir des variables localement, mais plutôt de faire un
Ça ne fonctionne pas, les deux
Le souci n'est pas de définir des variables localement, mais plutôt de faire un
readdans la boucle.
Ça ne fonctionne pas, les deux
readse télescoperont.
lEprofSonDkon
Messages postés
211
Date d'inscription
jeudi 13 décembre 2018
Statut
Membre
Dernière intervention
8 octobre 2022
13
>
boxR
Messages postés
4
Date d'inscription
mardi 14 mai 2019
Statut
Membre
Dernière intervention
14 mai 2019
Modifié le 14 mai 2019 à 14:48
Modifié le 14 mai 2019 à 14:48
commande | while IFS= read -d '' line; do read var </dev/tty; echo "$line -- $var"; done
« é voilà ! »
on pourrait aussi passer par des descripteurs de fichier...