Wie man einem einzelnen Zitat in awk entkommt

110

Ich möchte Folgendes tun

awk 'BEGIN {FS=" ";} {printf "'%s' ", $1}'

Auf diese Weise einem einfachen Anführungszeichen zu entkommen, funktioniert jedoch nicht

awk 'BEGIN {FS=" ";} {printf "\'%s\' ", $1}'

Wie macht man das? Danke für die Hilfe.

Codeforester
quelle
Eine Reihe von Sprachen entgeht Zitaten, indem sie zwei hintereinander setzen. Versuchen Sie das vielleicht.
Joshuahealy
Ich habe awk 'BEGIN {FS = "";} {printf "' '% s' '", $ 1}' versucht, aber es wurde kein einfaches Anführungszeichen gedruckt.
Diese Seite besagt, dass es unmöglich ist, ein einfaches Anführungszeichen in eine Zeichenfolge in einfachen Anführungszeichen aufzunehmen. Möglicherweise müssen Sie in doppelte Anführungszeichen konvertieren.
Joshuahealy
2
Es ist unmöglich, aber zwei benachbarte Shell-Strings in einfachen Anführungszeichen kleben zu einem Parameter zusammen. Und zwei einfach zitierte Shell-Strings, die von Nicht-Leerzeichen-Zeichen geklebt werden, kleben ebenfalls in einen großen Globus: 'abc'd'ef'is abcdef: Literal plus dplus Literal. Das dist außerhalb der Anführungszeichen, und Sie können es durch ersetzen, dum \'zu machen, 'abc'\''ef'was ausgewertet wird abc'ef.
Kaz

Antworten:

160

Dies ist vielleicht das, wonach Sie suchen:

awk 'BEGIN {FS=" ";} {printf "'\''%s'\'' ", $1}'

Das heißt, '\''wenn Sie die Öffnung schließen ', drucken Sie ein Literal, 'indem Sie es verlassen und schließlich wieder öffnen '.

Steve
quelle
47
Es hat nichts mit awk zu tun. Das 'Zeichen schließt das öffnende 'Shell-String-Literal. Das Shell-Literal unterstützt hierfür kein Backslash-Escape. Die Sequenz '\''der Trick: es schließt das einzelne Anführungszeichen Literal spezifiziert das Zitat - Zeichen (unter Verwendung einer Flucht , die sich außerhalb der einfachen Anführungszeichen Literale unterstützt) und dann wieder öffnet sich ein neues einzelnes Anführungszeichen Literal. Sie können es sich als vierstellige Escape-Sequenz vorstellen, um ein einfaches Anführungszeichen zu erhalten. :)
Kaz
2
@Steve: Vielen Dank für Ihre sehr nützliche Antwort. Du hast mir viele Kopfschmerzen erspart!
John Slegers
4
@syntaxerror Welche Anführungszeichen Sie zum Vorbereiten von Argumenten für den Aufruf verwenden, hängt awkausschließlich vom Befehlsinterpreter ab, den Sie zum Erstellen von Befehlszeilen verwenden. Das '{printf $2}'wird zu einem Argument für einen execveSystemaufruf oder ähnliches, bei dem es nur wie eine nullterminierte C-Zeichenfolge ohne einfache Anführungszeichen aussieht. Awk sieht die Zitate nie und sed auch nicht. Sie können in der Tat doppelte Anführungszeichen verwenden, aber doppelte Anführungszeichen verhindern nicht die Erweiterung der Shell $2, sodass Sie dem Dollarzeichen mit einem Backslash entkommen müssen, um es wörtlich zu machen : "{printf \$2}".
Kaz
4
@syntaxerror Benutzerdefiniert wird ein Inline-awk-Skript normalerweise mit einfachen Anführungszeichen maskiert, da die awk-Syntax häufig lexikalische Elemente enthält, die für die Shell spezifisch sind, z. B. Zeichenfolgenliterale in doppelten Anführungszeichen und nummerierte Felder, die durch Dollarzeichen gekennzeichnet sind. Wenn ein sed-regulärer Ausdruck (oder was auch immer) Shell-Syntax enthält, müssen Sie ebenfalls vorsichtig sein. sed -e "s/$FOO/$BAR/"funktioniert nicht, wenn der wörtliche Text $FOOdurch ersetzt werden soll $BAR. Der einfachste Weg wäre sed -e 's/$FOO/$BAR/.
Kaz
1
@syntaxerror Wenn Sie awk-Programme in doppelte Anführungszeichen setzen, werden Sie auf eine Menge Fluchtzeichen stoßen, wie z awk "{ print \"abc\", \$1 }". Jedes Mal, wenn ein doppeltes Anführungszeichen im awk-Programm angezeigt wird, muss es maskiert werden, damit das Shell-Anführungszeichen nicht geschlossen wird. Und vergleichen Sie dies: awk '{print "\\"}'(drucken Sie einen Backslash) mit dem, was es mit doppelten Anführungszeichen braucht : awk "BEGIN {print \"\\\\\" }", Puh! Beide Anführungszeichen müssen maskiert werden und beide Backslashes. Die Shell wird in konvertiert \\ , \ sodass wir \\\\ codieren müssen \\ .
Kaz
76

Ein einfaches Anführungszeichen wird mit dargestellt \x27

Wie in

awk 'BEGIN {FS=" ";} {printf "\x27%s\x27 ", $1}'

Quelle

tiagojco
quelle
16
+1, muss aber hinzugefügt werden: \x27ist eine Erweiterung; POSIX Awk erkennt nur \047. ( \47Ist auch in
Ordnung,
1
Wie beenden Sie \ x27, wenn Sie eine andere Nummer danach haben?
Jason Axelson
1
Jason, du verkettest zwei String-Literale: "AAA \ x27" "1". Oder Sie verwenden einfach Oktal.
Hemflit
9
Verwenden Sie immer octal ( \047), nicht hex ( \x27), Escape-Codes - siehe awk.freeshell.org/PrintASingleQuote .
Ed Morton
35

Eine andere Möglichkeit besteht darin, das einfache Anführungszeichen als awk-Variable zu übergeben :

awk -v q=\' 'BEGIN {FS=" ";} {printf "%s%s%s ", q, $1, q}'

Einfacheres Beispiel mit String-Verkettung:

# Prints 'test me', *including* the single quotes.
$ awk -v q=\' '{print q $0 q }' <<<'test me'
'test me'
mklement0
quelle
5
Dies ist klar und prägnant, insbesondere wenn Sie viele Anführungszeichen verwenden müssen.
Peter Gluck
18
awk 'BEGIN {FS=" "} {printf "\047%s\047 ", $1}'
Sergio K.
quelle
1
Solange ich mich erinnere, dass dies \047die oktale Escape-Sequenz für das einfache Anführungszeichen ist, finde ich diese Alternative am besten lesbar.
Anthony Geoghegan
4

Für kleine Skripte besteht eine optionale Möglichkeit, sie lesbar zu machen, darin, eine Variable wie die folgende zu verwenden:

awk -v fmt="'%s'\n" '{printf fmt, $1}'

Ich fand es praktisch in einem Fall, in dem ich ein Vielfaches des einfachen Anführungszeichens in der Ausgabe produzieren musste und das \ 047 es völlig unlesbar machte

user1708042
quelle