Archivia il contenuto in una variabile unix con newline


117

Ho un file di testo test.txt con il seguente contenuto:

text1
text2 

E voglio assegnare il contenuto del file a una variabile UNIX, ma quando lo faccio:

testvar=$(cat test.txt)
echo $testvar

il risultato è:

text1 text2

invece di

text1
text2 

Qualcuno può suggerirmi una soluzione per questo?

Risposte:


185

L'assegnazione non rimuove i caratteri di nuova riga, in realtà è il echofarlo. Devi semplicemente inserire virgolette attorno alla stringa per mantenere quelle nuove righe:

echo "$testvar"

Questo darà il risultato desiderato. Vedere la seguente trascrizione per una demo:

pax> cat num1.txt ; x=$(cat num1.txt)
line 1
line 2

pax> echo $x ; echo '===' ; echo "$x"
line 1 line 2
===
line 1
line 2

Il motivo per cui le nuove righe vengono sostituite con spazi non è interamente a che fare con il echocomando, piuttosto è una combinazione di cose.

Quando viene fornita una riga di comando, la bashdivide in parole secondo la documentazione per la IFSvariabile:

IFS: il separatore di campo interno utilizzato per la suddivisione delle parole dopo l'espansione ... il valore predefinito è <space><tab><newline>.

Ciò specifica che, per impostazione predefinita, uno qualsiasi di questi tre caratteri può essere utilizzato per dividere il comando in singole parole. Dopodiché, i separatori di parole sono spariti, tutto ciò che ti resta è un elenco di parole.

Combinalo con la echodocumentazione (un bashcomando interno) e vedrai perché gli spazi vengono emessi:

echo [-neE] [arg ...]: restituisce gli argomenti, separati da spazi, seguiti da una nuova riga.

Quando lo usi echo "$x", forza l'intera xvariabile ad essere una singola parola in base a bash, quindi non è divisa. Puoi vederlo con:

pax> function count {
...>    echo $#
...> }
pax> count 1 2 3
3
pax> count a b c d
4
pax> count $x
4
pax> count "$x"
1

Qui, la countfunzione stampa semplicemente il numero di argomenti forniti. Le varianti 1 2 3e a b c dlo mostrano in azione.

Quindi lo proviamo con le due varianti sulla xvariabile. L'uno senza citazioni spettacoli che ci sono quattro parole "test", "1", "test"e "2". Aggiungendo le virgolette diventa una sola parola "test 1\ntest 2".


Le virgolette ... ecco cosa mi mancava! Grazie!
anonimita

Vale anche la pena notare: Trailing a capo sarà rimosso dall'operatore comando di sostituzione in sé: Provalo in rete!
Giona

11

Ciò è dovuto alla variabile IFS (Internal Field Separator) che contiene una nuova riga.

$ cat xx1
1
2

$ A=`cat xx1`
$ echo $A
1 2

$ echo "|$IFS|"
|       
|

Una soluzione alternativa è reimpostare l'IFS in modo che non contenga la nuova riga, temporaneamente :

$ IFSBAK=$IFS
$ IFS=" "
$ A=`cat xx1` # Can use $() as well
$ echo $A
1
2
$ IFS=$IFSBAK

Per REVERTIRE questo orribile cambiamento per IFS:

IFS=$IFSBAK

Ho fatto questa modifica ma ora le mie altre cose non funzionano, per favore dimmi di resettarlo?
Pooja25

Se non ti serve per andare a una variabile, una battuta diretta:echo "$(IFS=''; cat text.txt)"
Curtis Yallop


3

Solo se qualcuno è interessato a un'altra opzione:

content=( $(cat test.txt) )

a=0
while [ $a -le ${#content[@]} ]
do
        echo ${content[$a]}
        a=$[a+1]
done

3

La tua variabile è impostata correttamente da testvar=$(cat test.txt). Per visualizzare questa variabile che consiste in nuovi caratteri di riga, aggiungi semplicemente virgolette doppie, ad es

echo "$testvar" 

Ecco l'esempio completo:

$ printf "test1\ntest2" > test.txt
$ testvar=$(<test.txt)
$ grep testvar <(set)
testvar=$'test1\ntest2'
$ echo "$testvar"
text1
text2
$ printf "%b" "$testvar"
text1
text2

0

L' envdirutilità fornisce un modo semplice per farlo. envdirutilizza i file per rappresentare le variabili di ambiente, con la mappatura dei nomi dei file ai nomi var env e la mappatura del contenuto dei file ai valori var env. Se il contenuto del file contiene una nuova riga, anche env var.

Vedi https://pypi.python.org/pypi/envdir

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.