Bagaimana cara menggunakan shell variabel dalam awk script?

Saya menemukan beberapa cara untuk lulus eksternal shell variabel untuk sebuah awk script, tapi aku'm bingung tentang ' dan ".

Pertama, saya mencoba dengan shell script:

$ v=123test
$ echo $v
123test
$ echo "$v"
123test

Kemudian mencoba awk:

$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123

Mengapa perbedaan?

Akhirnya saya mencoba ini:

$ awk 'BEGIN{print " '$v' "}'
$  123test
$ awk 'BEGIN{print ' "$v" '}'
awk: cmd. line:1: BEGIN{print
awk: cmd. line:1:             ^ unexpected newline or end of string 

I'm bingung tentang hal ini.

Mengomentari pertanyaan (2)
Larutan

Mendapatkan shell variabel ke awk

dapat dilakukan dalam beberapa cara. Beberapa lebih baik daripada yang lain. Ini harus mencakup sebagian besar dari mereka. Jika anda memiliki komentar, silakan tinggalkan di bawah ini.


Menggunakan -v (cara terbaik, paling portabel)

Gunakan -v pilihan: (P. S. menggunakan spasi setelah -v atau itu akan menjadi kurang portabel. E. g., awk -v var= tidak awk -vvar=)

variable="line one\nline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two

Ini harus kompatibel dengan sebagian besar awk, dan variabel yang tersedia di BEGIN block juga:

Jika anda memiliki beberapa variabel:

awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'

Peringatan. Sebagai Ed Morton menulis, escape sequences akan diterjemahkan jadi \t menjadi nyata tab dan tidak \t jika itu adalah apa yang anda cari. Dapat diselesaikan dengan menggunakan ENVIRON[] atau mengaksesnya melalui ARGV[]

PS Jika anda seperti tiga garis vertikal sebagai pemisah |||, hal ini dapat't akan melarikan diri, sehingga menggunakan -F"[|][|][|]"

Contoh mendapatkan data dari sebuah program/fungsi inn untuk awk (di sini saat ini digunakan)

awk -v time="$(date +"%F %H:%M" -d '-1 minute')" 'BEGIN {print time}'

Variabel setelah blok kode

Di sini kita mendapatkan variabel setelah awk code. Ini akan bekerja baik-baik saja asalkan anda tidak perlu variabel dalam BEGIN block:

variable="line one\nline two"
echo "input data" | awk '{print var}' var="${variable}"
or
awk '{print var}' var="${variable}" file

Ini juga bekerja dengan beberapa variabel awk '{print a,b,$0}' a="$var1" b="$var2" file

Menggunakan variabel dengan cara ini tidak bekerja di BEGIN block:

echo "input data" | awk 'BEGIN {print var}' var="${variable}"

Di sini-string

Variabel juga dapat ditambahkan ke awk menggunakan [di sini-string][1] dari kerang yang mendukung mereka (termasuk Bash):


awk '{print $0}' 
Komentar (6)

Tampaknya bahwa baik-tua LINGKUNGAN [tag:awk] built-in hash tidak disebutkan sama sekali. Contoh penggunaannya:

$ X=Solaris awk 'BEGIN{print ENVIRON["X"], ENVIRON["TERM"]}'
Solaris rxvt
Komentar (3)

Menggunakan salah satu dari ini tergantung bagaimana anda ingin garis miring terbalik di shell variabel ditangani (avar adalah sebuah awk variabel, svar adalah variabel shell):

awk -v avar="$svar" '... avar ...' file
awk 'BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...' "$svar" file

Lihat http://cfajohnson.com/shell/cus-faq-2.html#Q24 untuk rincian dan pilihan lainnya. Metode pertama di atas hampir selalu pilihan terbaik anda dan yang paling jelas semantik.

Komentar (0)

Anda bisa lulus di opsi baris perintah -v dengan nama variabel (v) dan nilai (=) dari variabel lingkungan ("${v}"):

% awk -vv="${v}" 'BEGIN { print v }'
123test

Atau untuk membuatnya lebih jelas (dengan jauh lebih sedikit `v):

% environment_variable=123test
% awk -vawk_variable="${environment_variable}" 'BEGIN { print awk_variable }'
123test
Komentar (0)

Anda dapat memanfaatkan ARGV:

v=123test
awk 'BEGIN {print ARGV[1]}' "$v"

Perhatikan bahwa jika anda akan terus masuk ke dalam tubuh, anda akan perlu untuk menyesuaikan ARGC:

awk 'BEGIN {ARGC--} {print ARGV[2], $0}' file "$v"
Komentar (0)

Saya harus menyisipkan tanggal pada awal baris dari file log dan's dilakukan seperti di bawah ini:

DATE=$(date +"%Y-%m-%d")
awk '{ print "'"$DATE"'", $0; }' /path_to_log_file/log_file.log

Hal ini dapat mengarahkan ke file lain untuk menyimpan

Komentar (2)

Aku hanya berubah @Jotne's jawaban untuk "untuk loop".

for i in `seq 11 20`; do host myserver-$i | awk -v i="$i" '{print "myserver-"i" " $4}'; done
Komentar (1)