Bagaimana cara membaca variabel dari file?

68

Saya ingin memasukkan nilai (string) pada skrip saya yang akan saya baca dari file teks.

Misalnya, alih-alih:

echo "Enter your name"
read name

Saya ingin membaca string dari file teks lain sehingga penerjemah harus membaca string dari file dan bukan input pengguna.

pengguna208413
sumber
1
Seperti apa file teks Anda? Apakah seluruh file 1 variabel atau mereka KEY=VALUEberpasangan? Solusinya sangat berbeda (jika itu yang terakhir, jawaban Takkat berlaku, mantan Radu)
kiri
1
@CiroSantilli bukan crossposted jika diposkan oleh pengguna lain, tidak ada yang namanya "duplikat lintas-situs". Satu-satunya hal yang harus dihindari adalah pertanyaan yang sama ditanyakan oleh pengguna yang sama di situs yang berbeda.
terdon

Jawaban:

98

Untuk membaca variabel dari file, kita dapat menggunakan perintah sourceatau ..

Mari kita asumsikan file tersebut berisi baris berikut

MYVARIABLE="Any string"

kita dapat mengimpor variabel ini menggunakan

#!/bin/bash

source <filename>
echo $MYVARIABLE
Takkat
sumber
16
Salah satu alasan mengapa Anda mungkin tidak ingin melakukannya dengan cara ini adalah karena apa pun yang ada di dalamnya <filename>akan berjalan di shell Anda, seperti rm -rf /, yang bisa sangat berbahaya.
Mark Ribau
3
Terlambat ke pesta, tetapi, tidak, itu tidak layak untuk ditandai ATAU sebagai jawabannya. Ini sumber file sumber bash lain yang BUKAN apa yang diminta OP. Dia bertanya bagaimana membaca isi FILE menjadi variabel. BUKAN cara menjalankan skrip lain yang menetapkan variabel . Jawaban yang benar adalah yang di bawah ini. name = $ (cat "$ file").
HörmannHH
2
OTOH, itu adalah jawaban untuk pertanyaan yang saya tanyakan kepada google dan Google membawa saya ke sini. Masa yang aneh, eh?
Michael Terry
1
Hebat juga berfungsi untuk banyak variabel! Point of @MarkRibau dipahami tetapi saya kira bahwa jika Anda benar file dalam skrip yang berbeda dan hanya harus melewati itu dengan baik dan terkontrol.
madlymad
1
Anda dapat menggunakan seduntuk menambahkan localkata kunci dan membuat skrip sedikit lebih aman dan tidak mencemari ruang lingkup global Anda. Jadi di dalam fungsi lakukan cat global_variables.sh | sed -e 's/^/local /' > local_variables.shdan kemudian gunakan . ./local_variables.sh. Apa pun yang Anda impor di fungsi hanya akan tersedia di fungsi itu. Perhatikan bahwa asumsi global_variables.shhanya berisi satu variabel per baris.
Nux
55

Mengingat bahwa Anda ingin semua konten file teks Anda disimpan dalam variabel Anda, Anda dapat menggunakan:

#!/bin/bash

file="/path/to/filename" #the file where you keep your string name

name=$(cat "$file")        #the output of 'cat $file' is assigned to the $name variable

echo $name               #test

Atau, dalam bash murni:

#!/bin/bash

file="/path/to/filename"     #the file where you keep your string name

read -d $'\x04' name < "$file" #the content of $file is redirected to stdin from where it is read out into the $name variable

echo $name                   #test
Radu Rădeanu
sumber
Saya tidak ingin menampilkan variabel, saya ingin agar variabel ini dibaca oleh skrip untuk diproses lebih lanjut. Saya sudah mencoba awk yang bertuliskan baris demi baris.
user208413
1
Oke, hapus echo $name . Saya menggunakannya hanya untuk tes. Selanjutnya Anda dapat menggunakan $namevariabel untuk memproses lebih lanjut di mana saja Anda inginkan dalam skrip Anda.
Radu Rădeanu
Saya tidak bisa menggunakannya di mana saja itu skrip saya karena skrip tidak tahu nilai variabel. Dalam kasus kami, nama variabel.
user208413
6
@ user208413 Nilai $namevariabel adalah string dari file Anda yang ditetapkan menggunakan cat $fileperintah. Apa yang tidak jelas atau sulit dipahami?
Radu Rădeanu
1
Itu berlebihan untuk menggunakan $filevariabel terpisah jika Anda hanya menggunakannya satu kali untuk memuat $namevariabel, cukup gunakancat /path/to/file
kiri
11

Dari dalam skrip Anda, Anda dapat melakukan ini:

read name < file_containing _the_answer

Anda bahkan dapat melakukan ini berkali-kali misalnya dalam satu lingkaran

while read LINE; do echo "$LINE"; done < file_containing_multiple_lines
mereka
sumber
atau untuk file dengan banyak item pada setiap baris. . . grep -v ^ # file | saat membaca abc; lakukan echo a = $ ab = $ bc = $ c; selesai
gaoithe
7

Salah satu cara alternatif untuk melakukan ini adalah dengan hanya mengarahkan input standar ke file Anda, di mana Anda memiliki semua input pengguna dalam urutan yang diharapkan oleh program. Misalnya, dengan program (disebut script.sh)

#!/bin/bash
echo "Enter your name:"
read name
echo "...and now your age:"
read age

# example of how to use the values now stored in variables $name and $age
echo "Hello $name. You're $age years old, right?"

dan file input (disebut input.in)

Tomas
26

Anda dapat menjalankan ini dari terminal dengan salah satu dari dua cara berikut:

$ cat input.in | ./script.sh
$ ./script.sh < input.in

dan itu akan setara dengan hanya menjalankan skrip dan memasukkan data secara manual - itu akan mencetak baris "Halo Tomas. Anda berusia 26 tahun, kan?".

Sebagai Radu Rădeanu telah sudah menyarankan , Anda bisa menggunakan catdalam naskah Anda untuk membaca isi file ke dalam avariable - dalam hal ini, Anda perlu setiap file berisi hanya satu baris, dengan hanya nilai yang Anda inginkan untuk variabel tertentu. Dalam contoh di atas, Anda akan membagi file input menjadi satu dengan nama (misalnya, name.in) dan satu dengan usia (katakanlah, age.in), dan mengubah read namedan read agebaris untuk name=$(cat name.in) dan age=$(cat age.in)masing-masing.

Tomas Aschan
sumber
Saya memiliki skrip berikut: vh = awk "NR == 3 {print; exit}" /var/www/test/test.txt dengan ini saya membaca baris 3 dari file teks bernama test.txt. Setelah saya mendapatkan string, saya ingin menggunakan string ini sebagai input untuk membuat direktori
user208413
1
Ubah itu menjadi vh=$(awk "NR==3 {print;exit}" /var/www/test.txt). Anda kemudian akan memiliki string disimpan dalam variabel $vh, sehingga Anda dapat menggunakannya seperti: mkdir "/var/www/$vh"- ini akan membuat folder dengan nama yang ditentukan di dalam / var / www.
Tomas Aschan
Saya telah melakukan cara ini tetapi masih tidak dapat membuat folder :(
user208413
@ user208413: Pesan kesalahan apa yang Anda dapatkan? "Tidak berhasil", sayangnya, bukan deskripsi masalah yang sangat membantu ...
Tomas Aschan
3
name=$(<"$file") 

Dari man bash:1785, substitusi perintah ini setara dengan name=$(cat "$file")tetapi lebih cepat.

hellork
sumber
2

Jawaban singkat:

name=`cat "$file"`
nedim
sumber
0

Jika Anda ingin menggunakan banyak string, Anda bisa menggunakan:

path="/foo/bar";
for p in `cat "$path"`;
do echo "$p" ....... (here you would pipe it where you need it) 

ATAU

Jika Anda ingin pengguna menunjukkan file

read -e "Specify path to variable(s): " path;
for p in 'cat "$path"';
do echo "$p" ............................
George
sumber
0
#! /bin/bash
#  (GPL3+) Alberto Salvia Novella (es20490446e)


variableInFile () {
    variable=${1}
    file=${2}

    source ${file}
    eval value=\$\{${variable}\}
    echo ${value}
}


variableInFile ${@}
Alberto Salvia Novella
sumber
0

Saya menggunakan ini untuk mendapatkan variabel tunggal dari file

GET_VAR=$(grep --color=never -Po "^${GET_VAR}=\K.*" "${FILE}" || true)

Ketika GET_VARtidak ditemukan di ${FILE}dalamnya akan kosong daripada menyebabkan kesalahan berkat || true.

Ini menggunakan grep -Pyang ada di GNU grep tetapi tidak default di semua grep pada saat penulisan ini.

Eric Nemchik
sumber
Ini sepertinya tidak berhasil untuk saya. $ Awal melempar kesalahan untuk karakter ilegal
ginna