Isi file ke dalam variabel unix dengan baris baru

117

Saya memiliki file teks test.txt dengan konten berikut:

text1
text2 

Dan saya ingin menetapkan konten file ke variabel UNIX, tetapi ketika saya melakukan ini:

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

hasilnya adalah:

text1 text2

dari pada

text1
text2 

Dapatkah seseorang menyarankan saya solusi untuk ini?

Hugo
sumber

Jawaban:

185

Tugas tidak menghapus karakter baris baru, sebenarnya echomelakukan ini. Anda hanya perlu memberi tanda kutip di sekitar string untuk mempertahankan baris baru tersebut:

echo "$testvar"

Ini akan memberikan hasil yang Anda inginkan. Lihat transkrip berikut untuk 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

The Alasan mengapa baris diganti dengan spasi tidak sepenuhnya dilakukan dengan echoperintah, melainkan kombinasi dari hal.

Saat diberi baris perintah, bagi bashmenjadi kata-kata sesuai dengan dokumentasi untuk IFSvariabel:

IFS: Pemisah Bidang Internal yang digunakan untuk pemisahan kata setelah perluasan ... nilai defaultnya adalah <space><tab><newline>.

Itu menentukan bahwa, secara default, salah satu dari tiga karakter tersebut dapat digunakan untuk membagi perintah Anda menjadi kata-kata individual. Setelah itu, kata pemisah hilang, yang tersisa hanyalah daftar kata.

Gabungkan itu dengan echodokumentasi ( bashperintah internal), dan Anda akan melihat mengapa spasi adalah keluaran:

echo [-neE] [arg ...]: Keluarkan args, dipisahkan oleh spasi, diikuti oleh baris baru.

Saat Anda menggunakannya echo "$x", ini memaksa seluruh xvariabel menjadi satu kata bash, oleh karena itu tidak dipecah. Anda dapat melihatnya dengan:

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

Di sini, countfungsinya hanya mencetak jumlah argumen yang diberikan. The 1 2 3dan a b c dvarian menunjukkan dalam tindakan.

Kemudian kami mencobanya dengan dua variasi pada xvariabel tersebut. Yang tanpa tanda kutip menunjukkan bahwa ada empat kata, "test", "1", "test"dan "2". Menambahkan tanda kutip menjadikannya satu kata tunggal "test 1\ntest 2".

paxdiablo
sumber
Kutipan ... itulah yang saya lewatkan! Terima kasih!
anonimit
Juga perlu diperhatikan: Mengikuti baris baru akan dihapus oleh operator substitusi perintah itu sendiri: Coba online!
Yunus
11

Hal ini disebabkan oleh variabel IFS (Internal Field Separator) yang berisi baris baru.

$ cat xx1
1
2

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

$ echo "|$IFS|"
|       
|

Solusinya adalah mengatur ulang IFS agar tidak memuat baris baru, untuk sementara :

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

Untuk MENGEMBALIKAN perubahan mengerikan ini untuk IFS:

IFS=$IFSBAK
DVK
sumber
Saya telah melakukan perubahan ini tetapi sekarang ada hal-hal lain yang tidak berfungsi, tolong beri tahu saya untuk mengatur ulang kembali?
Pooja25
Jika Anda tidak membutuhkannya untuk pergi ke variabel, satu baris langsung:echo "$(IFS=''; cat text.txt)"
Curtis Yallop
3

Hanya jika seseorang tertarik dengan opsi lain:

content=( $(cat test.txt) )

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

Variabel Anda disetel dengan benar oleh testvar=$(cat test.txt). Untuk menampilkan variabel ini yang terdiri dari karakter baris baru, cukup tambahkan tanda kutip ganda, mis

echo "$testvar" 

Berikut contoh lengkapnya:

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

The envdirutilitas menyediakan cara mudah untuk melakukan hal ini. envdirmenggunakan file untuk mewakili variabel lingkungan, dengan pemetaan nama file ke nama env var, dan pemetaan konten file ke nilai env var. Jika isi file berisi baris baru, begitu juga dengan env var.

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

Chris Johnson
sumber