Comment échapper aux guillemets simples dans sed?

92

Comment échapper à un guillemet simple dans une expression sed qui est déjà entourée de guillemets?

Par exemple:

sed 's/ones/one's/' <<< 'ones thing'
Thomas Bratt
la source
3
duplication possible de guillemets simples
buff
1
La réponse courte est " vous ne pouvez pas faire cela " - les solutions de contournement présentées fonctionnent toutes bien.
glenn jackman

Réponses:

150

sedCodes de devis avec guillemets doubles:

    $ sed "s/ones/one's/"<<<"ones thing"   
    one's thing

Je n'aime pas fuir les codes avec des centaines de contre-obliques - ça me fait mal aux yeux. Habituellement, je fais de cette façon:

    $ sed 's/ones/one\x27s/'<<<"ones thing"
    one's thing
Kent
la source
7
Cela ne semble pas fonctionner avec sed -i, une raison particulière?
SamAko
Il convient de noter que l'entourage des commandes sed avec des guillemets doubles permet à ces commandes d'être interpolées par le shell et peut conduire à des problèmes imprévus.
potong le
38

Une astuce consiste à utiliser la concaténation de chaînes shell des chaînes adjacentes et à échapper au guillemet intégré en utilisant l'échappement shell:

sed 's/ones/two'\''s/' <<< 'ones thing'

two's thing

Il y a 3 chaînes dans l'expression sed, que la coque cousent ensuite ensemble:

sed 's/ones/two'

\'

's/'

J'espère que cela aide quelqu'un d'autre!

Thomas Bratt
la source
peut-être une variante plus simple: sed 's / ones / two''s /' <<< 'ones thing'
gregory
@gregory: sed 's/ones/two''s/' <<< 'ones thing'Non, cela produit twos thing. Il manque le 'dans la sortie. Vous devez le faire de la manière décrite dans cette réponse.
wisbucky
@wisbucky Avec la version de sed que j'utilise (FreeBSD / macOS) sur zsh, il produit définitivement "deux choses".
gregory
grande aide l'homme en me le faisant savoir, coque puis cousu ensemble.
Prateek Gupta
6

La meilleure façon est d'utiliser $'some string with \' quotes \''

par exemple:

sed $'s/ones/two\'s/' <<< 'ones thing'
Jean C
la source
3
Le style C $'string'est spécifique à Bash, il n'est donc pas portable avec le shell POSIX.
tripleee
Ce n'est pas bashspécifique. Il est également disponible dans kshet zsh, mais oui, c'est une extension de POSIX, ce qui convient si vous n'écrivez pas de script portable. Le seul inconvénient est que vous devez également échapper à toute autre barre oblique inverse que vous utilisez.
dannyw
6

Utilisez simplement des guillemets doubles à l'extérieur de la commande sed.

$ sed "s/ones/one's/" <<< 'ones thing'
one's thing

Cela fonctionne aussi avec les fichiers.

$ echo 'ones thing' > testfile
$ sed -i "s/ones/one's/" testfile
$ cat testfile
one's thing

Si vous avez des guillemets simples et doubles dans la chaîne, ce n'est pas grave aussi. Échappez simplement aux guillemets.

Par exemple, ce fichier contient une chaîne avec des guillemets simples et doubles. J'utiliserai sed pour ajouter un guillemet simple et supprimer quelques guillemets doubles.

$ cat testfile
"it's more than ones thing"
$ sed -i "s/\"it's more than ones thing\"/it's more than one's thing/" testfile 
$ cat testfile 
it's more than one's thing
Stef Forrester
la source
Merci! J'adore les regex, j'aime sed et maintenant je t'aime <3
Gabriel A. Zorrilla
3

C'est un peu absurde , mais je ne pouvais pas \'dans sed 's/ones/one\'s/'le travail. Je cherchais cela pour créer un script shell qui s'ajoutera automatiquement import 'hammerjs';à mon src/main.tsfichier avec Angular.

Voici ce que j'ai fait pour travailler:

apost=\'
sed -i '' '/environments/a\
import '$apost'hammerjs'$apost';' src/main.ts

Donc, pour l'exemple ci-dessus, ce serait:

apost=\'
sed 's/ones/one'$apost's/'

Je ne sais pas pourquoi \'ne fonctionnerait pas par lui-même, mais voilà .

Ambrown
la source
0

Je sais que cela va ressembler à un flic, mais je ne pourrais jamais faire travailler sed quand il y avait à la fois des guillemets simples et doubles dans la chaîne. Pour aider les débutants comme moi qui ont des problèmes, une option consiste à diviser la chaîne. J'ai dû remplacer le code dans plus de 100 fichiers index.hmtl. Les chaînes avaient à la fois des guillemets simples et doubles, donc j'ai juste divisé la chaîne et remplacé le premier bloc par <!--et le deuxième bloc par -->. Cela a fait un désordre de mes fichiers index.html mais cela a fonctionné.

mcmacerson
la source
0

Certains échappements sur les terminaux AppleMacOSX échouent donc:

sed 's|ones|one'$(echo -e "\x27")'s|1' <<<'ones thing'

PaSe
la source
0

utilisez un séparateur de chaîne alternatif comme ":" pour éviter toute confusion avec des barres obliques différentes

sed "s:ones:one's:" <<< 'ones thing'

ou si vous souhaitez mettre en évidence le devis unique

sed "s:ones:one\'s:" <<< 'ones thing'

les deux reviennent

one's thing
cerveauélectronique
la source