GNU/Linux >> Belajar Linux >  >> Linux

Memaksa bash untuk memperluas variabel dalam string yang dimuat dari file

Banyak jawaban yang menggunakan eval dan echo jenis pekerjaan, tetapi merusak berbagai hal, seperti beberapa baris, mencoba keluar dari karakter meta shell, keluar di dalam template yang tidak dimaksudkan untuk diperluas oleh bash, dll.

Saya memiliki masalah yang sama, dan menulis fungsi shell ini, yang sejauh yang saya tahu, menangani semuanya dengan benar. Ini masih akan menghapus baris baru dari templat, karena aturan substitusi perintah bash, tetapi saya tidak pernah menemukan itu menjadi masalah selama yang lainnya tetap utuh.

apply_shell_expansion() {
    declare file="$1"
    declare data=$(< "$file")
    declare delimiter="__apply_shell_expansion_delimiter__"
    declare command="cat <<$delimiter"$'\n'"$data"$'\n'"$delimiter"
    eval "$command"
}

Misalnya, Anda dapat menggunakannya seperti ini dengan parameters.cfg yang sebenarnya adalah skrip shell yang hanya menetapkan variabel, dan template.txt yang merupakan template yang menggunakan variabel-variabel tersebut:

. parameters.cfg
printf "%s\n" "$(apply_shell_expansion template.txt)" > result.txt

Dalam praktiknya, saya menggunakan ini sebagai semacam sistem template yang ringan.


Saya menemukan apa yang menurut saya adalah jawaban atas pertanyaan ini:envsubst perintah:

echo "hello \$FOO world" > source.txt
export FOO=42
envsubst < source.txt

Ini menghasilkan:hello 42 world

Jika Anda ingin melanjutkan mengerjakan data dalam file destination.txt , Dorong ini kembali ke file seperti ini:

envsubst < source.txt > destination.txt

Jika belum tersedia di distro Anda, ada di paket GNU gettext .

@Rockallite

  • Saya menulis skrip pembungkus kecil untuk mengatasi masalah '$'.

(BTW, ada "fitur" envsubst, dijelaskan di https://unix.stackexchange.com/a/294400/7088untuk memperluas hanya beberapa variabel dalam input, tetapi saya setuju bahwa keluar dari pengecualian jauh lebih nyaman.)

Ini skrip saya:

#! /bin/bash
      ## -*-Shell-Script-*-
CmdName=${0##*/}
Usage="usage: $CmdName runs envsubst, but allows '\$' to  keep variables from
    being expanded.
  With option   -sl   '\$' keeps the back-slash.
  Default is to replace  '\$' with '$'
"

if [[ $1 = -h ]]  ;then echo -e >&2  "$Usage" ; exit 1 ;fi
if [[ $1 = -sl ]] ;then  sl='\'  ; shift ;fi

sed 's/\\\$/\${EnVsUbDolR}/g' |  EnVsUbDolR=$sl\$  envsubst  "[email protected]"

Linux
  1. Ganti Nama Mass File Bash Dengan Penghitung?

  2. Bash Script Untuk Menghapus File Terlama Dari Folder A?

  3. Bagaimana Cara Membuat Array Elemen Unik Dari String/array Di Bash?

  1. Menggunakan Referensi Ke Variabel Bash String Di Sed?

  2. Spasi Untuk Variabel Dalam Skrip Bash?

  3. Membaca Baris Dari File Dengan Bash:Untuk Vs. Ketika?

  1. Bagaimana cara menghapus baris baru dari file teks?

  2. Mengganti variabel lingkungan dalam file properti

  3. Redirect semua output ke file menggunakan Bash di Linux?