Gibt es eine Möglichkeit, einfache Anführungszeichen in der Shell zu umgehen?


11

Z.B. ich möchte sagen

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

Gibt es einen weniger umständlichen Weg, z. B. das Entkommen von einfachen Anführungszeichen?

Ja, ich weiß, dass ich schreiben kann

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

Bei dieser Frage geht es jedoch darum, in der Shell zu zitieren, nicht im Perl.

Ich bin interessiert, wie es in bashund cshan erster Stelle geht.

Antworten:


9

Dennis weist in seiner Antwort auf die üblichen Alternativen hin (einfach in Doppel, doppelt in einfach, einfache Anführungszeichen, die mit maskierten einfachen Anführungszeichen verknüpft sind; Sie haben bereits Perls anpassbare Anführungszeichenoperatoren erwähnt), aber vielleicht ist dies die direkte Antwort, die Sie gesucht haben zum.

In Bourne-ähnlichen Muscheln (sh, ksh, ash, dash, bash, zsh usw.) sind einfach zitierte Zeichenfolgen vollständig wörtlich. Dies macht es einfach, Zeichen einzuschließen, die die Shell sonst speziell behandeln würde, ohne sie maskieren zu müssen. Dies bedeutet jedoch, dass das einfache Anführungszeichen selbst nicht in Zeichenfolgen in einfachen Anführungszeichen eingeschlossen werden kann.

Ich weigere mich, überhaupt an die csh-Shells zu denken, da sie in anderer Hinsicht völlig kaputt sind (siehe Csh-Programmierung als schädlich angesehen ).


Vielen Dank. "Das ist unmöglich" - das ist die Antwort, die ich erwartet hatte :) Obwohl ich immer gehofft habe, dass es hier Dokumente gibt, die dieser Rolle gewidmet sind.
Codeholic

Anders als in Perl sind Bourne-ähnliche Shell-Dokumente hier nur direkt nützlich, um Eingaben über stdin bereitzustellen. Sie können sie natürlich in einfache Anführungszeichen setzen. Sie können auch den "Literalmodus" eines hier enthaltenen Dokuments aktivieren, indem Sie das Wort: (z blah <<\EOF … EOF. B.) zitieren . Sie können auch <<'EOF'und verwenden <<"EOF. Sie alle bedeuten hier wörtliche Dokumente (im Gegensatz zu Perl). Wenn Sie wirklich entschlossen blah "$(cat<<\EOF … EOF )" other argswären , könnten Sie dies tun (mit Zeilenumbrüchen, in die ich Leerzeichen in der Befehlssubstitution geschrieben habe; ksh und zsh können ohne die Katze auskommen , die anderen brauchen sie). Aber wäre es das wirklich wert?
Chris Johnsen

Ich möchte nur beachten, dass zsh einfache Anführungszeichen nicht ganz wörtlich sind. Zsh wird versuchen, ein '\ U' an einer beliebigen Stelle in einer Zeichenfolge in einfachen Anführungszeichen als Zeichencode zu interpretieren, z. B. das echo '\U0000068\U000069'Echo 'hi'. Ich bin mir nicht sicher warum, es sei denn, es ist ein Fehler in der Shell.
Matthew

1
@Matthew: Die Interpretation \Uin diesem Fall erfolgt über den eingebauten Echo- Befehl (dieses Verhalten kann durch -Eoder die Option BSD_ECHO und gesteuert werden -e). Sie können sehen, dass die Literalzeichenfolge in anderen Befehlen übergeben (und nicht anderweitig interpretiert) wird. zB printf %s\\n '\U0000068\U000069'.
Chris Johnsen

@ ChrisJohnsen Danke, ich bin neu bei zsh und habe das nicht bemerkt, aber du hast recht. Die Manpage sagte mir, -e ist Standard, aber zsh muss das überschreiben.
Matthew

5

Für mich ergeben alle Ihre Beispiele:

Hallo Welt!

Und das auch:

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

Und das:

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

Können Sie klarstellen, was Sie versuchen zu tun?

Wenn Sie in der Shell, z. B. Bash, Anführungszeichen als Teil der Zeichenfolge drucken möchten, entgeht eine Art von Anführungszeichen der anderen.

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

Bearbeiten:

Hier ist ein anderer Weg:

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

Das Leerzeichen nach dem Ausrufezeichen vermeidet einen Verlaufserweiterungsfehler. Ich hätte es set +Hstattdessen tun können .


1

Ich bin mir nicht sicher, ob meine Bearbeitung der vorherigen Antwort angezeigt wird:

Das Gleiche wie eine neue Antwort einfügen:

Alternativer Ansatz:

Als ich Ihre Lösung ausprobierte, konnte ich die 'immer noch nicht drucken lassen.

Aber ich habe mich an Ihrer Lösung orientiert und Folgendes versucht:

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

Der ASCII-Wert von 'ist 39.

Ich brauchte dies, um eine Inline-Bearbeitung für eine Reihe von Dateien vorzunehmen, die an einem interessierenden Ort hinzugefügt werden sollten.


1

Hier ist Dokument der beste Weg, um sich nicht um Flucht zu kümmern:

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

Sie können alle Erweiterungen vollständig unterbinden, indem Sie das hier zitierte Dokument verwenden:

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

Wenn Sie es als Argument anstelle der Eingabe übergeben möchten, können Sie xargs verwenden:

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

0

Ich weiß nicht, ob es eine Option gibt, um dies in Bash zu tun, aber mit zsh können Sie ''nach dem Aktivieren der RC_QUOTESOption verwenden. (Ich würde empfehlen, zsh auszuprobieren. Es ist größtenteils Bash-kompatibel und kann Bash emulieren, um noch mehr Kompatibilität zu gewährleisten.)

Mit bash (und immer noch die meiste Zeit mit zsh) verwende ich nur, '\''weil es einfacher zu lesen ist als '"'"'.

Ich habe absolut keine Ahnung, wie es in csh geht.


-1

Sie können \ 'und \ "verwenden, um Anführungszeichen mit Perl zu umgehen, wenn sie intern als Teil eines Perl-Skripts verwendet werden. Ich bin mir nicht sicher, ob die Befehlszeile dies akzeptiert. Sie können es versuchen und prüfen, ob es funktioniert.


3
Wenn es so einfach wäre, würde ich nicht fragen. Sie können es versuchen und prüfen, ob es funktioniert, bevor Sie eine Antwort veröffentlichen.
Codeholic
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.