#1 Le 10/10/2010, à 17:23
- boutor
[résolu] boucle bash avec sed
Bonsoir à tous,
Je n'arrive pas à passer un argument à sed en bash.
#! /bin/bash
dir=`pwd`
find -type f -name *.html > link.txt
tab=$(more link.txt)
for add in $tab ;
do
echo $add ;
sed '/stylesheet/ s/http:\//${dir}/' $add > "$add"_bak
done
Bash n'interprète pas ${dir}, ce qui paraît normal vu que c'est entre simple quote. Mais en mettant des doubles, ça plante.
Et je n'ai rien trouvé qui le fasse marcher.
Merci pour toute aide.
Dernière modification par boutor (Le 10/10/2010, à 17:59)
Hors ligne
#2 Le 10/10/2010, à 17:29
- Tomzz
Re : [résolu] boucle bash avec sed
Bonjour,
remplace:
sed '/stylesheet/ s/http:\//${dir}/' $add > "$add"_bak
par
sed "/stylesheet/ s/http:\//${dir}/" $add > "$add"_bak
Si je ne me trompe pas, les simples quotes empêchent la variable $dir d'être interprétée pas les doubles.
Dsl, je n'ai pas lu jusqu'au bout , tu as quoi dans ta variable, c'est vraiment pwd?
Bon, j'ai compris:
dir=$(pwd | sed 's/\//\\\//g') # on exécute pwd avec $() et on échappe les / avec le sed pour avoir par ex \/home\/user.
Ensuite des doubles quotes sur le dernier sed et ça devrait marcher
[edit le 12ieme] il y a aussi un souci avec find:
#! /bin/bash
dir=$(pwd | sed 's/\//\\\//g')
find -type f -name *.html -print > link.txt
for add in $(more link.txt);
do
echo $add ;
sed "/stylesheet/ s/http:\//${dir}/g" $add > "$add"_bak
done
Bon, je ne suis pas un kador, et je ne sais pas ce que fait more, ni /stylesheet/ dans la commande sed
Dernière modification par Tomzz (Le 10/10/2010, à 17:43)
Hors ligne
#3 Le 10/10/2010, à 17:59
- boutor
Re : [résolu] boucle bash avec sed
Oui c'est ce que je disais en dessous de mon code. Il faut des guillemets, mais avec les guillemets, ça plante.
/stylesheet/ permet de ne faire la substitution que sur les lignes contenant stylesheet.
En tout cas le problème venait de dir et non de ma commande sed. Je viesn de comprendre avec l'introduction de slash.
Merci Tomzz
Hors ligne
#4 Le 10/10/2010, à 18:06
- Tomzz
Re : [résolu] boucle bash avec sed
/stylesheet/ permet de ne faire la substitution que sur les lignes contenant stylesheet
Merci à toi, je faisait ça avec un grep en plus
Sinon, ton utilisation de more me parait bizare, je ne sais pas si on ne peux pas mettre directement le fichier dans la boucle for.
Sinon, pourquoi more plutôt que cat ?
Ta déclaration de variable: dir='pwd', si tu fais echo $dir derrière, tu obtient pwd c'est tout, pour exécuter la commande dans la variable, il faut dir=$(pwd)
Hors ligne
#5 Le 10/10/2010, à 18:15
- ehmicky
Re : [résolu] boucle bash avec sed
En tout cas le problème venait de dir et non de ma commande sed. Je viesn de comprendre avec l'introduction de slash.
Ca vient des deux, puisque tu ne peux pas passer une variable à sed avec les doubles guillemets, seulement le contenu de la variable ne doit pas contenir de slashs car cela fait buguer sed, il faut leur rajouter des backslashs derrière pour les échapper. Mais bon, à la base ton script a des problèmes, tu peux le raccourcir avec :
while read ; do
echo "$REPLY"
echo "${REPLY//http:\//$(pwd)}" > la_variable_que_tu_veux
done < <(grep --include="*.html" -hR "/stylesheet/" .)
Et tu n'a pas besoin d'utiluser sed alors que ${VAR//OLD/NEW} suffit et est 100 fois plus rapide, et full-bash (et ne pose pas le problème des slashs). Le remier echo n'imprime pas les lignes des fichiers .html ne contenant pas "/stylesheet" contrairement au tien, mais bon ça te donner une idée.
Edit : En fait, tu fais :
1) un find pour attraper les fichiers .html et les stocker dans un fichier temporaire
2) un $(more FICHIER) pour afficher le contenu de ce fichier, puis tu mets ce contenu dans une variable
3) tu utilises cette variable dans une boucle for
Alors que tu peux faire tout ça avec seulement :
find -type "f" -name "*.html" | while read...
parmi bien d'autres choix.
Par ailleurs, VARIABLE=$(more FICHIER) est vraiment pas correct. Il y a plusieurs redondances. More sert seulement si tu veux lire un fichier de manière interactive. Pour afficher son contenu, utilise cat. Par ailleurs, cat est souvent inutile, et on peut s'en passer (voir les bouts de code qui précèdent). En outre, ton $( ) n'est pas protégé par des double guillemets. Enfin, tu passes par une fichier temporaire, pour finalement retomber sur une variable, pour finir alors dans une boucle for, alors que tu peux faire tout ça d'un coup.
Enfin ` ` est déprécié, au profit de $( )
Dernière modification par ehmicky (Le 10/10/2010, à 18:59)
Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?
Hors ligne