Comment utiliser sed pour écrire dans un nom de file stocké dans une variable?

A partir d'un script bash , comment puis-je utiliser sed pour écrire dans un file où le nom de file est stocké dans une variable bash? La redirection de sortie ne fonctionnera pas parce que je veux éditer un file en place, en tirant des lignes qui correspondent à une regex dans un autre file et en les supprimant dans le premier file.

Quelque chose comme:

 sed -i '/^my regex here$/{;w file2;d;}' file1 

… mais où file1 et file2 sont tous deux des variables qui contiennent les noms de files. (Comme file2=$(mktemp) .)

Donc, ce que je veux vraiment, c'est l'expansion variable pour le nom de file, mais pas d'expansion pour le rest de la command sed , et laisser le tout comme un seul argument passé à la command sed .

Pour une raison quelconque, ce qui suit ne fonctionne pas:

 sed -i '/my regex here/{;w '"$file2"';d;}' $file1 

Il dit "inégalé {" et je ne vois pas pourquoi.

De toute façon je peux le faire?

Parce que vous utilisez une seule expression sed , tout ce qui suit après le w (y compris le } ) est interprété comme le nom de wfile :

L'argument wfile doit terminer la command d'édition.

Vous pouvez voir que si vous ajoutez une deuxième command } par exemple comme:

 sed -e '/my regex here/{w '"$file2"';d;}' -e '}' $file1 

alors les lignes qui correspondent à my regex here seront sauvegardées dans un file nommé whatever;d;}whatever ce que $file1 étend à.
La syntaxe correcte est via des commands séparées, avec plusieurs expressions:

 sed -e '/my regex here/{w '"$file1" -e 'd' -e '}' $file2 

ou une command par ligne:

 sed '/my regex here/{ w '"$file1"' d } ' $file2 

J'ai trouvé la réponse sur Stackoverflow sous "Comment puis-je laisser la command sed 'w savoir où se termine le nom du file?"

Comme terdon l'a souligné, la question n'est pas la variable – mais cela n'a rien à voir avec les accolades, non plus; essayez sed '/^l/w testing;p' et vous verrez qu'il ne jette aucune erreur, mais écrit toutes les lignes commençant par un l dans un file nommé testing;p

Le problème est en fait l'absence d'une nouvelle ligne après le nom de file.

La réponse consiste donc à utiliser une ligne de return inline dans la command sed:

 sed -i '/my regex here/{;w '"$file2"' d;}' $file1 

Ou , ce qui est beaucoup plus propre, utilisez deux arguments distincts:

 sed -i -e '/my regex here/{;w '"$file2" -e 'd;}' $file1 

Si vous n'aimez pas les deux guillemets adjacents (que vous pourriez facilement glisser), il suffit de mettre la command write dans son propre argument:

 sed -i -e '/^my regex here$/{' -e "w $file2" -e 'd;}' $file1 

Utilisez les guillemets doubles plutôt que les guillemets simples pour citer la command sed. Et n'oubliez pas d'échapper aux personnages appropriés.

Plus d'infos sur la citation des variables dans bash dans ce lien