Wie entkomme ich Sonderzeichen in einer Zeichenfolge?

Angenommen, $file enthält einen Wert eines Dateinamens, sagen Sie Dr" A.tif. Wie kann ich bei der Bash-Programmierung einem einfachen Anführungszeichen und einem anderen Sonderzeichen der $file entkommen, ohne das Sonderzeichen zu entfernen?

Update am 9. Juli 2014

Als Anfrage von @Gilles , Das folgende Code-Snippet, das Dr" A.tif nicht verarbeiten kann:

files=$(find /path/ -maxdepth 1 -name "*.[Pp][Dd][Ff]" -o -name "*.[Tt][Ii][Ff]") echo "${files}" > ${TEMP_FILE} while read file do newfile=$(echo "${file}" | sed "s, ,\\ ,g") ## line 1 done < ${TEMP_FILE} 

Nachdem ich das Antwort von @Patrick auf line 1, es scheint für mich zu funktionieren. Aber wenn ich eine Datei wie Dr\^s A.tif, printf scheint keine Hilfe zu sein, er zeigt mir Dr\^s\ A.tif. Wenn ich es manuell auf einer Konsole wie folgt versuche:

printf "%q" "Dr\^s A.tif"

Ich habe diese Ausgabe:

Dr\\\^s\ A.tif

Haben Sie eine Idee, wie Sie damit umgehen sollen?

Kommentare

  • in was Kontext erwarten Sie $ file zu verwenden? oder weist dieses Problem $ file die Zeichenfolge mit dem Sonderzeichen zu?
  • Tatsächlich gibt mir der Befehl find ein Array mit Dateilisten zurück. Und dann durchlaufe ich diese Dateiliste in $ file variable.
  • Sie ' haben hier einige richtige Antworten erhalten, aber sie sind wahrscheinlich nicht die Antworten auf die Frage, die Sie ' wirklich stellen. Aufgrund Ihres Kommentars hier vermute ich stark, dass Sie ' auf dem falschen Weg sind. Wir können ' Ihnen nicht viel helfen, weil Sie Ihren Code immer wieder nicht anzeigen. Ich empfehle jedoch, dass Sie lesen. Warum verschluckt sich mein Shell-Skript an Leerzeichen oder anderen Sonderzeichen? als Hintergrund. Zeigen Sie Ihr Skript und erklären Sie, was Sie tun möchten.

Antwort

Sie kann die mit %q integrierte printf verwenden, um dies zu erreichen. Zum Beispiel:

$ file="Dr" A.tif" $ printf "%q\n" "$file" Dr\"\ A.tif $ file=" foo$bar\baz`" $ printf "%q\n" "$file" \ foo\$bar\\baz\` 

Aus der Bash-Dokumentation zu printf:

In addition to the standard format specifications described in printf(1) and printf(3), printf interprets: %b expand backslash escape sequences in the corresponding argument %q quote the argument in a way that can be reused as shell input %(fmt)T output the date-time string resulting from using FMT as a format string for strftime(3) 

Kommentare

  • Dies funktioniert ' in bestimmten Fällen nicht .eg Wenn Sie doppelte Anführungszeichen beibehalten müssen.
  • @ user3467349 funktioniert dies problemlos mit Anführungszeichen. Ich ' wette, dass Sie ' etwas wie printf '%s' "foo" versuchen. Sie müssen zuerst verstehen, wie das Parsen von Argumenten in der Shell funktioniert. Siehe gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 geschieht vor # 6.
  • Könnten Sie Geben Sie ein Beispiel für diese Zeichenfolge an, die mit printf und keinen anderen Manipulationen gedruckt wurde. It doesn't have a: ""
  • Ihr Problem hat nichts damit zu tun printf. Ihr Problem ist, dass Sie ' nicht möchten, dass die Shell Ihren String analysiert. Dazu müssen Sie Ihre Eingabe so an die Shell übergeben, dass ' nicht einmal versucht, sie zu analysieren. Eine Möglichkeit, dies zu tun, wäre read -r -p 'input: ' && printf '%q\n' "$REPLY" und die Eingabe bereitzustellen, wenn Sie dazu aufgefordert werden.
  • Wie ich ' gesagt habe jetzt mehrmals. Nicht zu wissen, wie Rohdaten an die Shell übergeben werden, ist ' kein Problem mit printf. Vielleicht sollten Sie eine Frage stellen, anstatt eine Lösung zu kritisieren, die nichts mit Ihrem Problem zu tun hat.

Antwort

Versuchen Sie: –

file=Dr\"\ A.tif echo $file Dr" A.tif 

oder

file="Dr" A.tif" echo $file Dr" A.tif 

oder wenn die Zeichenfolge ein Double enthält Zitat: –

file="Dr" A.tif" echo $file Dr" A.tif 

Es gibt gute Tutorials zum Entkommen und Zitieren im Internet. Beginnen Sie mit diesem .

Antwort

Sie ziehen an „Sie müssen keine Dateinamen maskieren, die Sie in einem Skript verarbeiten. Das Escaping ist nur erforderlich, wenn Sie einen Dateinamen als Literal in ein Skript einfügen oder mehrere Dateinamen als einen einzigen übergeben möchten Eingabestream in ein anderes Skript.

Da Sie die Ausgabe von find durchlaufen, this ist eine der einfachsten Möglichkeiten (!), jeden möglichen Pfad zu behandeln :

while IFS= read -r -d "" do file_namex="$(basename -- "$REPLY"; echo x)" file_name="${file_namex%$"\nx"}" do_something -- "$file_name" done <(find "$some_path" -exec printf "%s\0" {} +) 

Antwort

schnell und (sehr) schmutzig

find . | sed "s/^/"/" | sed "s/$/"/" 

Antwort

Viele dieser Antworten, einschließlich der am besten bewerteten mit printf "%q", werden funktioniert nicht in allen Fällen ohne zusätzliche Manipulation.Ich würde Folgendes vorschlagen (Beispiel unten):

cat <<EOF; 2015-11-07T03:34:41Z app[postgres.0000]: [TAG] text-search query doesn"t contain lexemes: "" EOF

Kommentare

  • Entschuldigen Sie die Frage n00b, aber können Sie näher erläutern, wie Sie dies tatsächlich verwenden würden, um Zeichen in einer Zeichenfolge zu umgehen? Wenn ich den Code, den Sie in mein Terminal schreiben, kopiere, wird nur die 2015-11-07T03: 34: 41Z-App gedruckt Lexeme enthalten: " " … nichts wird entkommen.
  • Diese ' ist buchstäblich der Punkt, alle Sonderzeichen werden als wörtliche Zeichen interpretiert, nicht für ihre spezielle Bedeutung. Versuchen Sie stattdessen, " die obige Zeichenfolge " zu wiederholen, um den Unterschied zu erkennen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.