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.
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.
-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}'
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}"
Variabel juga dapat ditambahkan ke awk
menggunakan di sini-string dari kerang yang mendukung mereka (termasuk Bash):
awk '{print $0}' <<< "$variable"
test
Ini adalah sama seperti:
printf '%s' "$variable" | awk '{print $0}'
P. S. ini memperlakukan variabel sebagai file input.
LINGKUNGAN
inputSebagai TrueY menulis, anda dapat menggunakan LINGKUNGAN
untuk mencetak Variabel Lingkungan.
Pengaturan variabel sebelum menjalankan AWK, anda dapat mencetaknya seperti ini:
X=MyVar
awk 'BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}'
MyVar /bin/bash
ARGV
inputSebagai Steven Sen menulis, anda dapat menggunakan ARGV
untuk mendapatkan data ke awk:
v="my data"
awk 'BEGIN {print ARGV[1]}' "$v"
my data
Untuk mendapatkan data-data ke dalam kode itu sendiri, bukan hanya BEGIN:
v="my data"
echo "test" | awk 'BEGIN{var=ARGV[1];ARGV[1]=""} {print var, $0}' "$v"
my data test
Anda dapat menggunakan variabel dalam awk
code, tapi itu's berantakan dan sulit dibaca, dan sebagai Charles Duffy
poin keluar, versi ini juga dapat menjadi korban dari kode injeksi. Jika seseorang menambahkan hal-hal buruk untuk variabel, maka akan dieksekusi sebagai bagian dari awk
code.
Ini bekerja dengan mengeluarkan variabel dalam kode, sehingga menjadi bagian dari itu.
Jika anda ingin membuat sebuah awk
yang berubah secara dinamis dengan menggunakan variabel, anda dapat melakukannya dengan cara ini, tetapi TIDAK menggunakannya untuk variabel normal.
variable="line one\nline two"
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
Berikut adalah contoh kode injeksi:
variable='line one\nline two" ; for (i=1;i<=1000;++i) print i"'
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
1
2
3
.
.
1000
Anda dapat menambahkan banyak perintah untuk awk
dengan cara ini. Bahkan membuat crash dengan non perintah yang valid.
It's selalu baik untuk double quote variabel "$variabel"
Jika tidak, beberapa baris akan ditambahkan sebagai panjang satu baris.
Contoh:
var="Line one
This is line two"
echo $var
Line one This is line two
echo "$var"
Line one
This is line two
Kesalahan lain yang bisa anda dapatkan tanpa double quote:
variable="line one\nline two"
awk -v var=$variable 'BEGIN {print var}'
awk: cmd. line:1: one\nline
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: one\nline
awk: cmd. line:1: ^ syntax error
Dan dengan kutip tunggal, tidak memperluas nilai dari variabel:
awk -v var='$variable' 'BEGIN {print var}'
$variable
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.
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
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