Harici kabuk değişkenlerini bir awk
betiğine aktarmanın bazı yollarını buldum, ancak '
ve "
konusunda kafam karıştı.
Önce bir kabuk betiği ile denedim:
$ v=123test
$ echo $v
123test
$ echo "$v"
123test
Sonra awk denedim:
$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123
Fark neden kaynaklanıyor?
Son olarak bunu denedim:
$ 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
Bu konuda kafam karıştı.
Kabuk değişkenlerini
awk
içine almaçeşitli şekillerde yapılabilir. Bazıları diğerlerinden daha iyidir. Bu, çoğunu kapsamalıdır. Eğer bir yorumunuz varsa, lütfen aşağıya bırakın.
-v
(En iyi yol, en taşınabilir)vseçeneğini kullanın: (Not:
-vden sonra bir boşluk kullanın, aksi takdirde daha az taşınabilir olacaktır. Örneğin,
awk -v var=değil
awk -vvar=`)
variable="line one\nline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two
Bu, çoğu awk
ile uyumlu olmalıdır ve değişken BEGIN
bloğunda da kullanılabilir:
Birden fazla değişkeniniz varsa:
awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'
Uyarı. Ed Morton'un yazdığı gibi, kaçış dizileri yorumlanacaktır, böylece \t
gerçek bir tab
olur ve aradığınız şey buysa \t
olmaz. ENVIRON[]kullanılarak çözülebilir veya
ARGV[]` ile erişilebilir
PS Üç dikey çubuğu ayırıcı olarak |||
seviyorsanız, -F"[|][|][|]"
kullanın.
Bir program/fonksiyon hanından
awk
için veri alma örneği (burada tarih kullanılır)
awk -v time="$(date +"%F %H:%M" -d '-1 minute')" 'BEGIN {print time}'
Burada awk
kodundan sonra değişkeni alıyoruz. Bu, BEGIN
bloğunda değişkene ihtiyacınız olmadığı sürece iyi çalışacaktır:
variable="line one\nline two"
echo "input data" | awk '{print var}' var="${variable}"
or
awk '{print var}' var="${variable}" file
Bu aynı zamanda çoklu değişkenlerle de çalışır
awk '{print a,b,$0}' a="$var1" b="$var2" file
Değişkeni bu şekilde kullanmak BEGIN
bloğunda çalışmaz:
echo "input data" | awk 'BEGIN {print var}' var="${variable}"
Değişkenler, onları destekleyen kabuklardan (Bash dahil) bir here-string kullanılarak awk
a da eklenebilir:
awk '{print $0}' <<< "$variable"
test
Bu aynı şey:
printf '%s' "$variable" | awk '{print $0}'
Not: Bu, değişkeni bir dosya girişi olarak ele alır.
ENVIRON
girişiTrueY'nin yazdığı gibi, Çevre Değişkenlerini yazdırmak için ENVIRON
kullanabilirsiniz.
AWK'yi çalıştırmadan önce bir değişken ayarlayarak, bunu şu şekilde yazdırabilirsiniz:
X=MyVar
awk 'BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}'
MyVar /bin/bash
ARGV
girişiSteven Penny'nin yazdığı gibi, verileri awk'a almak için ARGV
kullanabilirsiniz:
v="my data"
awk 'BEGIN {print ARGV[1]}' "$v"
my data
Verileri sadece BEGIN'e değil, kodun içine almak için:
v="my data"
echo "test" | awk 'BEGIN{var=ARGV[1];ARGV[1]=""} {print var, $0}' "$v"
my data test
awkkodu içinde bir değişken kullanabilirsiniz, ancak bu dağınık ve okunması zor bir koddur ve
Charles Duffynin de belirttiği gibi, bu sürüm kod enjeksiyonunun kurbanı olabilir. Eğer birisi değişkene kötü bir şey eklerse, bu
awk` kodunun bir parçası olarak çalıştırılacaktır.
Bu, kod içindeki değişkeni çıkararak çalışır, böylece kodun bir parçası haline gelir.
Değişkenlerin kullanımıyla dinamik olarak değişen bir awk
yapmak istiyorsanız, bunu bu şekilde yapabilirsiniz, ancak normal değişkenler için KULLANMAYIN.
variable="line one\nline two"
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
İşte bir kod enjeksiyonu örneği:
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
Bu şekilde `awk'a çok sayıda komut ekleyebilirsiniz. Hatta geçerli olmayan komutlarla çökmesini bile sağlayabilirsiniz.
Değişkenleri çift tırnak içine almak her zaman iyidir "$variable"
Aksi takdirde, birden fazla satır uzun tek bir satır olarak eklenecektir.
Örnek:
var="Line one
This is line two"
echo $var
Line one This is line two
echo "$var"
Line one
This is line two
Çift tırnak olmadan alabileceğiniz diğer hatalar:
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
Ve tek tırnak ile değişkenin değerini genişletmez:
awk -v var='$variable' 'BEGIN {print var}'
$variable
Kabuk değişkenlerindeki ters eğik çizgilerin nasıl işlenmesini istediğinize bağlı olarak bunlardan birini kullanın (avar
bir awk değişkenidir, svar
bir kabuk değişkenidir):
awk -v avar="$svar" '... avar ...' file
awk 'BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...' "$svar" file
Ayrıntılar ve diğer seçenekler için http://cfajohnson.com/shell/cus-faq-2.html#Q24 adresine bakın. Yukarıdaki ilk yöntem neredeyse her zaman en iyi seçenektir ve en belirgin semantiğe sahiptir.
Komut satırı seçeneği]1 -v
ile bir değişken adı (v
) ve ortam değişkeninin değerini (=
) ("${v}"
) iletebilirsiniz:
% awk -vv="${v}" 'BEGIN { print v }'
123test
Ya da daha açık hale getirmek için (çok daha az v
ile):
% environment_variable=123test
% awk -vawk_variable="${environment_variable}" 'BEGIN { print awk_variable }'
123test