web-dev-qa-db-fra.com

Utiliser une variable dans une commande sed

Je n'arrive pas à utiliser une variable dans une commande sed, par exemple:

sed "24s/.*/"$ct_tname"/" file1.sas > file2.sas

Je voudrais $ct_tname la variable, pas littéralement $ct_tname, c'est ce que je reçois toujours.

Quelqu'un sait comment faire fonctionner cela?

Le problème est en fait plus complexe et j'ai omis certaines informations.

ct_fname="%let outputfile="/user/ct_"$1".csv";"

Ici, $1 est l'argument passé au début de mon script bash (sed est exécuté dans un script bash).

Cela ne fonctionne pas correctement, mais il s'exécute si je remplace ct_fname avec

ct_fname="%let table=ct_$1;"

Existe-t-il un moyen d'obtenir le premier ct_fname à passer avec succès?

26
user788171

vous devez utiliser des guillemets doubles (") au lieu de guillemets simples ('). les guillemets simples transmettent leur contenu littéralement, sans traduire de variables (expansion).

essayer

sed "24s/.*/\"$ct_tname\"/" file1.sas > file2.sas

btw, si vous allez éditer un fichier (c'est-à-dire si file2.sas est un fichier temporaire), vous devriez utiliser ed à la place.

38
c00kiemon5ter

Dans mon cas, je viens de remplacer les guillemets simples par les doubles:

for a in $(cat ext.cnf); do sed -n "/$a$/p" file1 >> file2; done

Pour l'instant, ça marche bien ...

4
Garik

Le problème est que lorsque $ct_fname est substitué, sed voit extra / séparateurs, donc

sed "24s/.*/"$ct_tname"/" file1.sas > file2.sas

devient

sed "24s/.*/"%let outputfile=/user/ct_ARGUMENT1.csv;"/" file1.sas > file2.sas

et vous obtiendrez une erreur sed car il y a 5 / au lieu des 3 attendus.

Remplacez plutôt vos séparateurs sed par un caractère inutilisé comme | ou :, et les guillemets simples ou doubles fonctionneront très bien:

sed '24s|.*|'$ct_tname'|' file1.sas > file2.sas
sed "24s|.*|"$ct_tname"|" file1.sas > file2.sas
1
Roger Dueck

Vous devez utiliser double (") guillemets, avec un simple (') indique que la valeur de la variable n'est pas remplacée. Puisque vous avez des guillemets doubles dans votre texte de remplacement, vous devez y échapper:

sed "24s/.*/\"$ct_tname\"/" file1.sas > file2.sas
1
Kenneth Hoste

Les variables shell ne sont pas développées à l'intérieur de guillemets simples. Essayez plutôt ceci:

sed "24s/.*/\"$ct_tname\"/" file1.sas > file2.sas
1
twalberg

D'autres réponses se concentrent sur l'utilisation de guillemets doubles échappés dans leurs exemples. Notez que ce n'est pas toujours ce que vous voulez:

$ FOO="auie"; echo foo123bar|sed "s/123/\"$FOO\"/"
foo"auie"bar
$ FOO="auie"; echo foo123bar|sed "s/123/$FOO/"
fooauiebar
$ FOO="auie"; echo fooauiebar|sed "s/\"$FOO\"/123/"
fooauiebar
$ FOO="auie"; echo fooauiebar|sed "s/$FOO/123/"
foo123bar
1