Bagaimana cara membaca baris file yang berbeda untuk variabel yang berbeda?


14

Saya ingin membaca baris yang berbeda dari file teks ke variabel yang berbeda. Sebagai contoh

input.txt:

line1 foo foobar bar
line2 bar
line3 foo
line4 foobar bar

Saya ingin hasil ini untuk disimpan dalam variabel var1, var2, var3dan var4sehingga

var1=line1 foo foobar bar
var2=line2 bar

dan seterusnya.

Bisakah seseorang tolong katakan padaku bagaimana ini dilakukan. Saya mencoba menggunakan evaldalam for loop. Sepertinya tidak berhasil.



3
Ini pendekatan yang buruk. Karena pada dasarnya satu-satunya alasan untuk variabel set adalah untuk melakukan sesuatu dengan mereka, dan karena ada sejumlah besar alat khusus yang dirancang untuk melakukan hal-hal dengan setiap baris teks dalam sebuah file (AWK, Sed, grep, cut, et. Al.), jauh lebih baik melakukan apa yang perlu Anda lakukan. Jangan mengelola mikro dalam skrip shell; mengatur alat untuk menyelesaikan pekerjaan.
Wildcard

Jawaban:


20

Anda akan melakukannya:

unset -v line1 line2
{ IFS= read -r line1 && IFS= read -r line2; } < input.txt

Atau:

{ line1=$(line) && line2=$(line); } < input.txt

(Kurang efisien karena linejarang built-in dan kebanyakan shell perlu garpu untuk mengimplementasikan substitusi perintah. lineJuga bukan lagi perintah standar).

Untuk menggunakan loop:

unset -v line1 line2 line3
for var in line1 line2 line3; do
  IFS= read -r "$var" || break
done < input.txt

Atau untuk secara otomatis mendefinisikan nama-nama variabel sebagai line<++n>:

n=1; while IFS= read -r "line$n"; do
  n=$((n + 1))
done < input.txt

Perhatikan bahwa bashmendukung variabel array dan readarraybuiltin untuk membaca baris ke dalam array:

readarray -t line < input.txt

Namun perhatikan bahwa bertentangan dengan kebanyakan shell lain, bashindeks array mulai dari 0 bukan 1 (diwarisi dari ksh), jadi baris pertama akan berada di ${line[0]}, bukan ${line[1]}(meskipun seperti yang ditunjukkan @Costas , Anda dapat membuat readarray(alias mapfile) mulai menulis nilai di indice 1 ( basharray juga bertentangan dengan sebagian besar kerang lain yang jarang array) dengan -O 1).

Lihat juga: Memahami "IFS = read -r line"?


12

Saya akan menawarkan untuk menggunakan array untuk tugas seperti itu

mapfile -t -O 1 var <input.txt

jadi Anda akan memiliki setiap baris ${var[1]}, ${var[2]}dan seterusnya


One-liner ini bekerja dengan sangat baik. Memecahkan masalah bagi saya.
Matt Zabojnik

0

Ini tidak sepenuhnya apa yang Anda minta, tetapi mungkin cocok untuk kebutuhan Anda. Anda dapat membuat cerita bersambung data dengan Awk. Perhatikan bahwa ini akan rusak jika $ 1 Anda bukan nama variabel yang valid:

awk '
function quote(str,   d, m, x, y, z) {
  d = "\47"; m = split(str, x, d)
  for (y in x) z = z d x[y] (y < m ? d "\\" d : d)
  return z
}
{
  print $1 "=" quote($0)
}
' input.txt > /tmp/input.sh
. /tmp/input.sh

Hasil:

$ echo "$line1"
line1 foo foobar bar

Ini kode serius yang aneh! Tampaknya Anda menggunakan awk untuk mengubah seluruh file input menjadi skrip bash yang kemudian Anda sumber. Saya memiliki gagasan yang tidak jelas tentang apa yang dilakukan kutipan (). Nama variabel yang lebih deskriptif akan membantu. Bisakah Anda menjelaskan lebih banyak hal?
Joe
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.