'\ n' in `IFS = $ '\ n' è una variabile?


12

Noto che impostare newline IFSdovrebbe avere un $ come prefisso

IFS=$'\n'

ma se imposta i due punti, giusto

IFS=:

È \nuna variabile?

Risposte:


21

Che $'...'in bashnon è il parametro di espansione, si tratta di un particolare tipo di citazione introdotta da ksh93che espande quelli \n, \x0a, \12i codici ad un carattere di nuova riga. zshanche aggiunto \u000a. ksh93e bashhanno anche \cjmentre si zshha \C-J. ksh93supporta anche variazioni come \x{a}.

La $è una stecca che è una forma o espansione. Ma in ogni caso, differisce da altre forme di espansioni che usano $(come $((1 + 1)), $paramo $(cmd)) in quanto non viene eseguita tra virgolette doppie o qui documenti (gli echo "$'x'"output $'x'in tutte le shell non sono specificati per POSIX) e la sua espansione non è soggetta a divisione + glob, è decisamente più vicino a un operatore di quotazione che a un operatore di espansione.

IFS=\nfisserebbe IFS a n( \viene trattato come un operatore citare) e IFS="\n"o IFS='\n'fisserebbe IFS ai due caratteri rovesciati e n.

Puoi anche usare:

IFS='
'

o

IFS="
"

o

IFS=$'
'

Per passare un ritorno a capo letterale, anche se questo è meno leggibile (e non si vede altro che usare le cose come set listin vise $IFScontiene altri caratteri spaziatura in quel codice).

IFS=:, IFS=':', IFS=":", IFS=$':'Tutti IFS set per :modo che non importa quale si usa.

$'...'è supportato (con variazioni) mediante almeno: ksh93, zsh, bash, mksh, busybox sh, FreeBSD sh. ksh93e bashhanno anche una $"..."forma di virgolette utilizzata per la localizzazione del testo, anche se raramente viene utilizzata in quanto è scomoda da distribuire e utilizzare in modo portabile e affidabile.

Le shell ese fishpossono anche usare \nal di fuori delle virgolette per espandersi a newline.

Alcuni strumenti come printf, alcune implementazioni echoo awkpossono anche espandersi \nda soli. Ad esempio, si può fare:

printf '\n'
awk 'BEGIN{printf "\n"}'
echo
echo '\n\c' # UNIX compliant echos only

all'output del carattere di nuova riga, ma si noti che:

IFS = $ (printf '\ n')

non funzionerà perché il comando substitution ( $(...)) rimuove tutti i caratteri di nuova riga finali. Puoi comunque usare:

eval "$(printf 'IFS="\n"')"

Che funziona perché l'output di printftermina in un "personaggio, non in una nuova riga.

Ora, per completezza, nella rcshell e nelle derivate (come eso akanga), $'\n'c'è davvero l'espansione di quella \nvariabile (una variabile il cui nome è la sequenza di due caratteri \e n). Quei proiettili non hanno una limitazione quali caratteri nomi delle variabili possono contenere e avere un solo tipo di citazioni: '...'.

$ rc
; '\n' = (foo bar)
; echo $'\n'
foo bar
; echo $'\n'(1)
foo

rcle variabili sono anche tutte esportate nell'ambiente, ma almeno nella variante Unix di rc, per nomi di variabili come \n, la versione della variabile di ambiente subisce una forma di codifica:

; env | grep foo | sed -n l
__5cn=foo\001bar$

( 0x5cessendo il valore byte di ASCII \; vedi anche come quella variabile di matrice è stata codificata con un byte 0x1 come separatore).


1
+1per il solito livello disumano di conoscenza
Steven Penny,

10

Questa è la citazione ANSI-C :

Le parole del modulo $'string'sono trattate in modo speciale. La parola si espande in string, con i caratteri con escape backslash sostituiti come specificato dallo standard ANSI C.

Quindi $'\n'è sostituito da una nuova riga.

Questo non è correlato all'espansione dei parametri della shell , nonostante l'uso di $.


6

Stringhe come $'\n'sono state introdotte ksh93e attualmente non fanno parte dello standard POSIX.

Consentono di utilizzare la maggior parte delle fughe allo stesso modo, ad es. $'\u2345'E le fughe supportate anche da echo.

Nota che se non ti piace (nel caso di ksh93 o bash) usare quel metodo di escape, puoi comunque usare:

IFS='
'

che è equivalente ma più difficile da leggere.

A proposito: questa estensione ha già superato il comitato standard POSIX, ma è prevista per SUSv8 che dovrebbe apparire non prima del 2020 perché dobbiamo prima lavorare sul nostro ritardo dietro l'attuale elenco di bug.


Le $'...'espansioni differiscono da quella di echo. Sono più simili a quelli per l'argomento format di printf. Per echo, è richiesto uno 0 in \0123mentre per $'...'e printfformato, \0123sarebbe \012una nuova riga seguita da una lettera 3
Stéphane Chazelas,

1
Si noti che le $'...'specifiche sono ancora in discussione. Vi sono ancora diversi problemi da risolvere con la formulazione attualmente proposta.
Stéphane Chazelas,

IIRC, è stato chiuso ma è stato riaperto. A causa del fatto che c'è ancora molto tempo prima che diventi efficace, non vedo un vero problema.
schily,

1
È stato chiuso, ho sollevato diverse obiezioni, è stato riaperto, è stato quindi modificato, ci sono ancora diversi problemi (molti dei quali \uxxxxsull'espansione) e nessuna risoluzione in vista che possa accogliere le implementazioni esistenti. Quindi potrebbe non passare alla prossima versione POSIX. Forse potrebbero lasciare \uxxxxfuori l' espansione per issue8, quindi possiamo ancora avere almeno $'\n'.
Stéphane Chazelas,
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.