Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#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 big_smile, 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

boutor a écrit :

/stylesheet/ permet de ne faire la substitution que sur les lignes contenant stylesheet

Merci à toi, je faisait ça avec un grep en plus wink

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