Czy istnieje sposób na uniknięcie pojedynczych cudzysłowów w powłoce?

11

Np. chcę powiedzieć

perl -e 'print '"'"'Hello, world!'"'"', "\n";'

Czy istnieje mniej niewygodny sposób, np. Unikanie pojedynczych cudzysłowów?

Tak, wiem, że umiem pisać

perl -e 'print q[Hello, world!], "\n"'
perl -e 'print "Hello, world!\n"'

Ale to pytanie dotyczy cytowania w powłoce, a nie w Perlu.

Jestem zainteresowany jak to zrobić w bashi cshw pierwszej kolejności.

Codeholic
źródło

Odpowiedzi:

9

Dennis wskazuje w swojej odpowiedzi zwykłe alternatywy (ciągi podwójne w podwójnym, podwójne w jednym, pojedyncze cytaty połączone z unikniętymi pojedynczymi cudzysłowami; wspominałeś już o dostosowywanych operatorach cytatów Perla), ale być może jest to bezpośrednia odpowiedź, której szukałeś dla.

W powłokach podobnych do Bourne'a (sh, ksh, ash, dash, bash, zsh itp.) Ciągi pojedynczego cudzysłowu są całkowicie dosłowne. Ułatwia to dołączanie znaków, które w przeciwnym razie powłoka traktowałaby specjalnie bez konieczności ucieczki, ale oznacza to, że pojedynczy znak cudzysłowu nie może być zawarty w ciągach pojedynczego cudzysłowu.

Nie chcę nawet myśleć o powłokach typu csh, ponieważ są one całkowicie zepsute pod innymi względami (patrz Programowanie Csh uważane za szkodliwe ).

Chris Johnsen
źródło
Dziękuję Ci. „To niemożliwe” - takiej odpowiedzi się spodziewałem :) Chociaż zawsze miałem nadzieję, że to tutaj dokumenty poświęcone są tej roli.
codeholic
W przeciwieństwie do Perla, dokumenty w powłoce Bourne'a są tutaj bezpośrednio przydatne tylko do wprowadzania danych wejściowych przez stdin. Możesz oczywiście wstawiać w nich pojedyncze cytaty. Możesz także włączyć „tryb dosłowny” dokumentu tutaj, cytując słowo: (np blah <<\EOF … EOF. ) . Możesz także użyć <<'EOF'i <<"EOF. Wszystkie oznaczają dosłowne dokumenty (w przeciwieństwie do Perla). Jeśli byłeś naprawdę zdeterminowany, możesz to zrobić blah "$(cat<<\EOF … EOF )" other args(używając nowego wiersza, w którym napisałem spacje w podstawieniu polecenia; ksh i zsh mogą obejść się bez kota , inni tego potrzebują). Ale czy naprawdę byłoby warto?
Chris Johnsen
Chcę tylko zauważyć, że pojedyncze cytaty zsh nie są dosłowne. Zsh spróbuje zinterpretować „\ U” w dowolnym miejscu ciągu pojedynczego cudzysłowu jako kod znakowy, np. echo '\U0000068\U000069'Echo „cześć”. Nie jestem pewien, dlaczego, chyba że jest to błąd w powłoce.
Matthew
1
@Matthew: Interpretacja \Uw tym przypadku odbywa się za pomocą wbudowanego polecenia echa (to zachowanie może być kontrolowane przez -Eopcję lub BSD_ECHO i -e). Możesz zobaczyć, że ciąg literalny jest przekazywany (i nie interpretowany w inny sposób) w innych poleceniach; np printf %s\\n '\U0000068\U000069'.
Chris Johnsen,
@ChrisJohnsen Dzięki, jestem nowy w Zsh i nie zdawałem sobie z tego sprawy, ale masz rację. Strona man powiedziała mi, że -e jest domyślna, ale zsh musi to zastąpić.
Matthew
5

Dla mnie wszystkie twoje przykłady dają:

Witaj świecie!

I robi to:

perl -e 'print "Hello, world!", "\n";'

I to:

perl -e 'print '\''Hello, world!'\'', "\n";'

Czy możesz wyjaśnić, co próbujesz zrobić?

W powłoce, takiej jak Bash, jeśli chcesz drukować cudzysłowy jako część ciągu, jeden typ cudzysłowów ucieka przed drugim.

$ echo '"Hello, world!"'
"Hello, world!"
$ echo "'Hello, world!'"
'Hello, world!'

Edytować:

Oto inny sposób:

$ perl -e 'print "\047Hello, world!\047", "\n";'
'Hello, world!'
$ echo -e "\047Hello, world! \047"
'Hello, world! '

Spacja po wykrzykniku pozwala uniknąć błędu ekspansji historii. Mógłbym set +Hzamiast tego zrobić .

Wstrzymano do odwołania.
źródło
1

Nie jestem pewien, czy pojawi się moja edycja poprzedniej odpowiedzi:

Wklej to samo, co nowa odpowiedź:

Alternatywne podejście:

Kiedy wypróbowałem Twoje rozwiązanie, nadal nie mogłem wydrukować „.

Ale wziąłem podpowiedź z twojego rozwiązania i wypróbowałem następujące:

$ perl -e '$foo = chr(39); print "${foo}Hello, world ${foo}", "\n";'
'Hello, world '

Wartość ASCII wynosząca „39”.

Potrzebowałem tego, aby dokonać bezpośredniej edycji wielu plików, aby dodać je w interesującym miejscu.

Kaushik B
źródło
1

Tutaj dokument jest najlepszym sposobem, aby nie przejmować się ucieczką:

$ cat <<EOF
my $var = "Hello";
print $text, ', world!', "\n";'
EOF

Możesz całkowicie zablokować wszelką ekspansję, używając cytowanego tutaj dokumentu:

$ cat <<'EOF'
my $var = "Hello";
print $text, ', world!', "\n";'
EOF

Jeśli chcesz przekazać go jako argument zamiast danych wejściowych, możesz użyć xargs:

$ xargs -0 <<'EOF' perl -e
my $var = "Hello";
print $text, ', world!', "\n";'
EOF
Jérôme Pouiller
źródło
0

Nie wiem, czy jest taka opcja w bash, ale z zsh możesz użyć ''po włączeniu tej RC_QUOTESopcji. (Polecam wypróbowanie zsh; jest w większości kompatybilny z bash i może emulować bash, aby uzyskać jeszcze większą kompatybilność).

Z bash (i nadal przez większość czasu z zsh), po prostu używam, '\''ponieważ jest łatwiejszy do odczytania niż '"'"'.

Nie mam pojęcia, jak to zrobić w csh.

SilverWolf - Przywróć Monikę
źródło
-1

Możesz użyć \ 'i \ ", aby uniknąć cudzysłowów z perlem, jeśli jest używany wewnętrznie jako część skryptu perla. Nie jestem jednak pewien, czy linia poleceń to zaakceptuje. Możesz spróbować i sprawdzić, czy to działa.

Micheasz
źródło
3
Gdyby to było takie proste, nie zapytałbym. Możesz spróbować i sprawdzić, czy to działa, zanim opublikujesz odpowiedź.
codeholic