Come sfuggire a una singola citazione all'interno di awk


111

Voglio fare quanto segue

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

Ma sfuggire alle virgolette singole in questo modo non funziona

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

Come fare questo? Grazie per l'aiuto.


Un certo numero di lingue sfugge alle virgolette mettendone due in fila, magari provaci.
joshuahealy

Ho provato awk 'BEGIN {FS = "";} {printf "' '% s' '", $ 1}', ma non è stata stampata nessuna virgoletta.

Questa pagina dice che è impossibile includere una virgoletta singola in una stringa con virgolette singole. Forse dovrai convertire in virgolette doppie.
joshuahealy

2
È impossibile, ma due stringhe di shell adiacenti con virgolette singole si incollano insieme in un parametro. E anche due stringhe di shell con virgolette singole incollate da caratteri non spazi vuoti si incollano in un grande glob: 'abc'd'ef'is abcdef: literal plus dplus literal. La dè al di fuori delle citazioni, e si può sostituirlo dcon \'fare 'abc'\''ef'che valuta a abc'ef.
Kaz

Risposte:


160

Questo forse è quello che stai cercando:

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

Cioè, '\''quando chiudi l'apertura ', quindi stampa un letterale 'sfuggendolo e infine apri di 'nuovo.


48
Non ha niente a che fare con awk. Il 'carattere chiude la 'stringa della shell di apertura letterale. Il valore letterale della shell non supporta l'escape di backslash per questo. La sequenza '\''fa il trucco: chiude il letterale, specifica il carattere preventivo virgoletta singola (usando una fuga che è supportato al di fuori di letterali virgoletta singola) e poi riapre un nuovo apice singolo letterale. Puoi pensarla come una sequenza di escape di quattro caratteri per ottenere una singola citazione. :)
Kaz

2
@ Steve: Grazie mille per la tua risposta molto utile. Mi hai risparmiato un sacco di mal di testa!
John Slegers

4
@syntaxerror Le virgolette che usi per preparare argomenti da invocare awksono puramente una questione dell'interprete dei comandi che stai usando per comporre le righe di comando. Il '{printf $2}'viene trasformato in qualche argomento per una execvechiamata di sistema o simili, in cui appena si presenta come un null terminata stringa di C senza virgolette singole. Awk non vede mai le virgolette e nemmeno sed. È possibile virgolette infatti uso, ma le doppie virgolette non impedisce l'espansione della shell di $2, in modo da avere per sfuggire al simbolo del dollaro con un backslash per renderlo letterale: "{printf \$2}".
Kaz

4
@syntaxerror Per consuetudine, uno script awk in linea viene solitamente sottoposto a escape con virgolette singole, perché la sintassi di awk spesso contiene elementi lessicali che sono speciali per la shell, come le stringhe letterali tra virgolette doppie e campi numerati denotati dal segno del dollaro. Se un'espressione regolare sed (o qualsiasi altra cosa) contiene la sintassi della shell, devi anche stare attento. sed -e "s/$FOO/$BAR/"non funzionerà se l'intento è sostituire il testo letterale $FOOcon $BAR. Il modo più semplice sarebbe sed -e 's/$FOO/$BAR/.
Kaz

1
@syntaxerror Se racchiudi programmi awk tra virgolette doppie, ti imbatterai in molti escaping, come awk "{ print \"abc\", \$1 }". Ogni volta che una virgoletta doppia appare nel programma awk, deve essere evitata in modo che non chiuda la virgoletta della shell. E confronta questo: awk '{print "\\"}'(stampa una barra rovesciata) con quello che serve con virgolette doppie awk "BEGIN {print \"\\\\\" }":, Phew! Entrambe le virgolette devono essere precedute da caratteri di escape ed entrambe le barre rovesciate. La shell si converte \\ in \ quindi dobbiamo \\\\ codificare \\ .
Kaz

76

Una singola citazione è rappresentata usando \x27

Come in

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

fonte


16
+1, ma è necessario aggiungere: \x27è un'estensione; POSIX Awk riconosce solo \047. ( \47va bene anche se non è seguito da una cifra ottale.)
hemflit

1
Come finisci \ x27 se hai un altro numero dopo?
Jason Axelson

1
Jason, concatena due stringhe letterali: "AAA \ x27" "1". Oppure usi solo ottale.
hemflit

9
Usa sempre octal ( \047), non hex ( \x27), codici di escape - vedi awk.freeshell.org/PrintASingleQuote .
Ed Morton

35

Un'altra opzione è passare le virgolette singole come una variabile awk :

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

Esempio più semplice con concatenazione di stringhe:

# Prints 'test me', *including* the single quotes.
$ awk -v q=\' '{print q $0 q }' <<<'test me'
'test me'

5
Questo è chiaro e conciso, soprattutto se devi usare molte citazioni.
Peter Gluck

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

1
Finché ricordo che \047è la sequenza di escape ottale per il carattere di virgolette singole, trovo che questa alternativa sia la più leggibile.
Anthony Geoghegan,

4

Per piccoli script un modo opzionale per renderlo leggibile è usare una variabile come questa:

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

L'ho trovato conveninet in un caso in cui dovevo produrre molte volte il carattere di virgolette singole nell'output e \ 047 lo rendevano totalmente illeggibile

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.