web-dev-qa-db-fra.com

Comment remplacer un chemin par un autre chemin dans sed?

J'ai un script csh (bien que je puisse changer de langue s'il a une pertinence) où je dois:

sed s/AAA/BBB/ file

Le problème est que AAA et BBB sont des chemins, et contiennent donc '/'. AAA est fixe, je peux donc dire:

sed s/\\\/A\\\/A\\\A/BBB/ file

Cependant, BBB est basé sur des variables, notamment $ PWD. Comment échapper au '/' dans $ PWD?

OU y a-t-il un autre moyen que je devrais faire entièrement?

29
Brian Postow

sed peut utiliser n’importe quel séparateur au lieu de / dans la commande s. Utilisez simplement quelque chose qui ne se trouve pas dans vos chemins:

s+AAA+BBB+

etc.

Sinon (et si vous ne voulez pas deviner), vous pouvez prétraiter votre chemin avec sed pour échapper aux barres obliques:

pwdesc=$(echo $PWD | sed 's_/_\\/_g')

et faites ensuite ce dont vous avez besoin avec $pwdesc.

59
Lev Levitsky

Dans les cas où la chaîne de remplacement ou la chaîne de modèle contient des barres obliques, vous pouvez utiliser le fait que GNU sed autorise un autre délimiteur pour la commande de substitution. Les choix courants pour le délimiteur sont le caractère de canal | ou le hash # - le meilleur choix de caractère de délimitation dépendra souvent du type de fichier en cours de traitement. Dans votre cas, vous pouvez essayer

sed -i 's#/path/to/AAA#/path/to/BBB#g' your_file

Remarque: Le g après le dernier # consiste à modifier toutes les occurrences du fichier si vous souhaitez modifier la première ou la valeur, n'utilisez pas g 

18
c0m3t

Utiliser csh pour les scripts sérieux est généralement non recommandé . Cependant, cela est tangent à la question à traiter.

Vous êtes probablement après quelque chose comme:

sed -e "s=$oldpath=$newpath="

où la variable Shell $oldpath contient la valeur à remplacer et $newpath contient le remplacement, et il est supposé qu'aucune de ces variables ne contient un signe égal. Autrement dit, vous êtes autorisé à choisir le délimiteur sur le modèle et éviter le délimiteur habituel / évite les problèmes de barres obliques dans les noms de chemin. Si vous pensez que = pourrait apparaître dans vos noms de fichier, choisissez un élément moins susceptible d'apparaître, tel que control-A ou control-G.

4
Jonathan Leffler
sed -i "s|$fileWithPath|HAHA|g" file
3
pylover

Vous pouvez utiliser une extension de parenthèse ${i/p/r} pour échapper aux barres obliques . Dans ce cas, ${i//p/r} pour échapper à toutes les occurrences.

$p1=${p1//\//\\/}
$p2=${p2//\//\\/}
sed s/$p1/$p2/ file

Ou, plus concis, sur une seule ligne sed s/${p1//\//\\/}/${p2//\//\\/}/ file

Les deux premières barres // sont un séparateur dans l’extension entre parenthèses indiquant que nous correspondons à toutes les occurrences, alors \/ sert à échapper à la barre oblique dans le modèle de recherche, le / en tant que second séparateur dans l’extension, puis \\/ est le remplacement, dans lequel le la barre oblique inverse doit être évitée.

0
FrViPofm