C'è un modo per sfuggire alle virgolette singole nella shell?


11

Per esempio. voglio dire

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

C'è un modo meno imbarazzante per farlo, ad esempio sfuggire alle virgolette singole?

Sì, lo so che posso scrivere

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

Ma questa domanda riguarda la citazione nella shell, non nel Perl.

Sono interessato a come farlo bashe cshin primo luogo.

Risposte:


9

Dennis indica le solite alternative nella sua risposta (stringhe singole-in-doppie, doppie in singole, a virgoletta singola concatenate con virgolette singole sfuggite; hai già citato gli operatori di virgolette personalizzabili di Perl), ma forse questa è la risposta diretta che stavi cercando per.

In gusci tipo Bourne (sh, ksh, ash, dash, bash, zsh, ecc.) Le stringhe a virgoletta singola sono completamente letterali. Ciò semplifica l'inclusione di caratteri che la shell altrimenti tratterebbe in modo speciale senza doverli sfuggire, ma significa che il singolo carattere di virgoletta non può essere incluso nelle stringhe tra virgolette singole.

Mi rifiuto persino di pensare alle shell di tipo csh poiché sono completamente rotte sotto altri aspetti (vedi Programmazione Csh considerata dannosa ).


Grazie. "Questo è impossibile" - è la risposta che mi aspettavo :) Anche se ho sempre sperato che qui sono i documenti dedicati a questo ruolo.
codeholic

A differenza di Perl, i shell simili a Bourne qui sono utili solo direttamente per fornire input tramite stdin. Ovviamente puoi inserire solo virgolette. Puoi anche abilitare la "modalità letterale" di un documento qui citando la parola: (es blah <<\EOF … EOF. ) . Puoi anche usare <<'EOF'e <<"EOF. Significano tutti letteralmente qui documenti (a differenza del Perl). Se tu fossi davvero determinato, potresti farlo blah "$(cat<<\EOF … EOF )" other args(usando le nuove righe in cui ho scritto degli spazi nella sostituzione del comando; ksh e zsh possono fare a meno del gatto , gli altri ne hanno bisogno). Ma ne varrebbe davvero la pena?
Chris Johnsen,

Voglio solo notare che le virgolette singole di zsh non sono del tutto letterali. Zsh proverà a interpretare un '\ U' ovunque in una stringa a virgoletta singola come un codice carattere, ad esempio echo '\U0000068\U000069'echi 'ciao'. Non so perché, a meno che non sia un bug nella shell.
Matteo,

1
@Matthew: L'interpretazione di \Uin tal caso viene eseguita dal comando echo incorporato (questo comportamento può essere controllato -Edall'opzione BSD_ECHO e -e). Puoi vedere che la stringa letterale viene passata (e non interpretata diversamente) in altri comandi; es printf %s\\n '\U0000068\U000069'.
Chris Johnsen,

@ChrisJohnsen Grazie, sono nuovo di zsh e non me ne sono reso conto ma hai ragione. La pagina man mi ha detto -e è di default ma zsh deve sovrascriverlo.
Matteo,

5

Per me, tutti i tuoi esempi producono:

Ciao mondo!

E così fa questo:

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

E questo:

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

Puoi chiarire cosa stai cercando di fare?

Nella shell, come Bash, se si desidera stampare le virgolette come parte della stringa, un tipo di virgolette sfugge all'altro.

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

Modificare:

Ecco un altro modo:

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

Lo spazio dopo il punto esclamativo evita un errore di espansione della cronologia. Avrei potuto set +Hinvece fare .


1

Non sono sicuro se la mia modifica alla risposta precedente verrà visualizzata:

Incollare lo stesso di una nuova risposta:

Approccio alternativo:

Quando ho provato la tua soluzione, non riuscivo ancora a stampare.

Ma ho preso spunto dalla tua soluzione e ho provato quanto segue:

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

Il valore ASCII di 'è 39.

Ne avevo bisogno per fare una modifica in linea a un mucchio di file da aggiungere "in un luogo di interesse.


1

Qui il documento è il modo migliore per non preoccuparsi di scappare:

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

Puoi inibire completamente tutte le espansioni usando il documento citato qui:

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

Se vuoi passarlo come argomento anziché come input, puoi usare xargs:

$ xargs -0 <<'EOF' perl -e
my $var = "Hello";
print $text, ', world!', "\n";'
EOF

0

Non so se c'è un'opzione per farlo in bash, ma con zsh puoi usare ''dopo aver attivato l' RC_QUOTESopzione. (Consiglierei di provare zsh; è per lo più compatibile con bash e può emulare bash per una compatibilità ancora maggiore.)

Con bash (e ancora la maggior parte delle volte con zsh), lo uso solo '\''perché è più facile da leggere di '"'"'.

Non ho assolutamente idea di come farlo in CSH.


-1

Puoi usare \ 'e \ "per evitare virgolette con perl se usato internamente come parte di uno script perl. Non sono sicuro però che la riga di comando lo accetti. Puoi provarlo e vedere se funziona.


3
Se fosse così facile, non lo chiederei. Puoi provarlo e vedere se funziona prima di pubblicare una risposta.
Codeholic
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.