Qual è il significato esatto di IFS = $ '\ n'?
-
29-09-2019 - |
Domanda
Se il seguente esempio, che imposta la variabile di ambiente IFS
ad un carattere di avanzamento riga ...
IFS=$'\n'
- Che cosa significa il segno dollaro media esattamente
- Che cosa fa in questo specifico caso?
- Dove posso saperne di più su questo uso specifico (Google non consente caratteri speciali nelle ricerche e non so cosa cercare in altro modo)?
So quello che la variabile d'ambiente IFS
è, e quello che il personaggio è \n
(avanzamento riga), ma perché non basta usare la seguente forma:
IFS="\n"
(che non funziona)?
Ad esempio, se voglio scorrere ogni riga di un file e si desidera utilizzare un ciclo for, avrei potuto fare questo:
for line in (< /path/to/file); do
echo "Line: $line"
done
Tuttavia, questo non funzionerà a destra a meno che IFS
è impostato su un carattere di avanzamento riga. Per farlo funzionare, avrei dovuto fare questo:
OLDIFS=$IFS
IFS=$'\n'
for line in (< /path/to/file); do
echo "Line: $line"
done
IFS=$OLDIFS
Nota: non ho bisogno di un altro modo per fare la stessa cosa, so che molti altri già ... Sono curioso solo che $'\n'
e mi chiedevo se qualcuno mi potrebbe dare una spiegazione su di esso.
Soluzione
Normalmente bash
non interpreta sequenze di escape in stringhe letterali. Quindi, se si scrive o \n
"\n"
o '\n'
, che non è un'interruzione di riga -. È la lettera n
(nel primo caso) o una barra rovesciata seguita dalla lettera n
(negli altri due casi)
$'somestring'
è un sintassi per stringhe con sequenze di escape . Quindi, a differenza '\n'
, $'\n'
in realtà è una riga.
Altri suggerimenti
Proprio per dare il costrutto il suo nome ufficiale : le stringhe del modulo $'...'
sono chiamati ANSI C-citato stringhe .
Cioè, come in [ANSI] stringhe C, le sequenze di escape a gioco sono riconosciuti e ampliata per il loro equivalente letterale (vedi sotto per la lista completa delle sequenze di escape supportati ).
Dopo questa espansione, le stringhe $'...'
si comportano allo stesso modo come stringhe '...'
- vale a dire, sono trattati come letterali NON fatte salve eventuali ulteriori [] espansioni della shell .
Per esempio, si espande $'\n'
ad un carattere di nuova riga letterale -. Che è qualcosa di un regolare letterale stringa di bash (se '...'
o "..."
) non possono fare [1]
Un'altra caratteristica interessante è che ANSI C-citato stringhe possono sfuggire '
(apici) come \'
, che, '...'
(regolari stringhe racchiuse tra virgolette singole) non può:
echo $'Honey, I\'m home' # OK; this cannot be done with '...'
Elenco di sequenze di escape supportate :
Backslash sequenze di escape, se presenti, vengono interpretati come segue:
\ a alert (campana)
\ b backspace
\ e \ E un carattere di escape (non ANSI C)
\ f form feed
\ n nuova riga
\ r ritorno a capo
\ t tabulazione orizzontale
\ v scheda verticale
\ backslash
\' apice singolo
\" virgolette
\ nnn il carattere a otto bit il cui valore è il valore ottale nnn (una a tre cifre)
\ xHH il carattere a otto bit il cui valore è il valore esadecimale HH (una o due cifre esadecimali)
\ uhhhh il (10646 ISO / IEC) carattere Unicode cui valore è il valore esadecimale HHHH (una a quattro cifre esadecimali)
\ UHHHHHHHH il (10646 ISO / IEC) carattere Unicode cui valore è il valore esadecimale HHHHHHHH (uno a otto cifre esadecimali)
\ cx un carattere di controllo-x
Il risultato espanso è unico citato, come se il simbolo del dollaro non era stato presente.
[1] È possibile, tuttavia, incorporare reale a capo in '...' e "..." stringhe; vale a dire, è possibile definire le stringhe che si estendono su più righe.
http://www.linuxtopia.org/online_books/bash_guide_for_beginners/sect_03_03.html :
Parole in forma " 'STRING' $" sono trattati in modo speciale. La parola espande in una stringa, caratteri backslash-escape sostituiti come specificato dallo standard ANSI-C. sequenze di escape backslash può essere trovato nella Bash documentation.found
Credo che sia costringendo lo script per sfuggire alla linea di alimentazione per il corretto standard ANSI-C.
Re recuperare il default IFS- questo OLDIFS=$IFS
non è necessario. Eseguire nuovi IFS in subshell per evitare sovrascrivendo i IFS predefinite:
ar=(123 321); ( IFS=$'\n'; echo ${ar[*]} )
Inoltre non credo davvero a recuperare completamente le vecchie IFS. Si dovrebbe virgolette alla linea di evitare di rompere, come OLDIFS="$IFS"
.
stringhe ANSI C-citati è un punto chiave. Grazie a @ mklement0.
È possibile verificare le stringhe ANSI C-citato con il comando od.
echo -n $'\n' | od -c
echo -n '\n' | od -c
echo -n $"\n" | od -c
echo -n "\n" | od -c
Uscite:
0000000 \n
0000001
0000000 \ n
0000002
0000000 \ n
0000002
0000000 \ n
0000002
È possibile conoscere il significato chiaramente dalle uscite.
E 'come recuperare il valore da una variabile:
VAR='test'
echo VAR
echo $VAR
sono diversi, in modo che il simbolo del dollaro valuta in sostanza il contenuto.