Memiliki yang berikut di salah satu fungsi shell saya:
function _process () {
awk -v l="$line" '
BEGIN {p=0}
/'"$1"'/ {p=1}
END{ if(p) print l >> "outfile.txt" }
'
}
, jadi ketika dipanggil sebagai _process $arg
, $arg
akan dilewati sebagai $1
, dan digunakan sebagai pola pencarian. Ini bekerja seperti ini, karena shell mengembang $1
di tempat pola awk! Juga l
dapat digunakan di dalam program awk, sedang dideklarasikan dengan -v l="$line"
. Semua baik-baik saja
Apakah mungkin dengan cara yang sama memberikan pola untuk mencari sebagai variabel?
Mengikuti tidak akan berhasil,
awk -v l="$line" -v search="$pattern" '
BEGIN {p=0}
/search/ {p=1}
END{ if(p) print l >> "outfile.txt" }
'
, sebagai awk tidak akan menafsirkan /search/
sebagai variabel, tetapi secara harfiah.
if (p) ...
$0 ~ pattern
, dan itu tidak berhasil, namun dengan/'"$1"'/
itu tidak berfungsi !? : O$line
diambil, pencarian pola dilakukan pada output dariwhois $line
,$line
datang dari file di blok WHILE DO.$line
- lakukan di pertanyaan Anda untuk pemformatan yang tepat.Memiliki masalah dalam
awk
memperluas urutan pelarian ANSI C (seperti\n
untuk baris baru,\f
untuk umpan formulir,\\
untuk backslash dan sebagainya) di$1
. Jadi itu menjadi masalah jika$1
mengandung karakter backslash yang umum dalam ekspresi reguler (dengan GNUawk
4.2 atau lebih tinggi, nilai yang dimulai dengan@/
dan diakhiri/
, juga merupakan masalah ). Pendekatan lain yang tidak menderita dari masalah itu adalah menulisnya:Seberapa buruk akan tergantung pada
awk
implementasinya.Semua
awk
s bekerja sama untuk urutan pelarian yang valid:(konten
$a
lulus apa adanya)(
\\
diubah menjadi\
dan\b
diubah menjadi karakter backspace).sumber
\d{3}
untuk menemukan tiga digit, itu tidak akan berfungsi seperti yang diharapkan, jika saya mengerti Anda dengan baik?\d
yang bukan urutan pelarian C yang valid, itu tergantung padaawk
implementasi Anda (jalankanawk -v 'a=\d{3}' 'BEGIN{print a}'
untuk memeriksa). Tetapi untuk\` or
\ b, yes definitely. (BTW, I don't know of any awk implementations that understands
\ d` artinya digit).\d' treated as plain
d 'd {3}, jadi saya kira saya akan memiliki masalah dalam kasus ini?ENVIRON["PATTERN"]
denganPATTERN
variabel lingkungan. Jika Anda ingin menggunakan variabel shell, Anda harus mengekspornya terlebih dahulu (export variable
) atau menggunakanENV=VALUE awk '...ENVIRON["ENV"]'
sintaks lewat env-var seperti dalam jawaban saya.Coba sesuatu seperti:
sumber
/regex/
dalam hal menemukan pola, ini bisa menjadi solusi yang bagus. Saya akan mencoba.Tidak, tetapi Anda dapat dengan mudah menginterpolasikan pola tersebut ke dalam string yang dikutip ganda yang Anda lewatkan dengan awk:
Perhatikan bahwa Anda sekarang harus melarikan diri dari awk literal yang dikutip ganda, tetapi ini masih merupakan cara paling sederhana untuk mencapai ini.
sumber
$pattern
berisi spasi, contoh saya di atas akan berfungsi karena $ 1 dilindungi dengan tanda kutip ganda "$ 1", namun tidak tahu apa yang terjadi dalam kasus Anda.'
, kemudian melindungi$1
melalui tanda kutip ganda dan kemudian mengaitkan string dengan tanda kutip tunggal lainnya untuk paruh kedua program awk. Jika saya mengerti dengan benar, ini seharusnya memiliki efek yang persis sama dengan melindungi$1
via tanda kutip tunggal luar - awk tidak pernah melihat tanda kutip ganda yang Anda tempatkan di sekitarnya.$pattern
mengandung^/ {system("rm -rf /")};
, maka Anda dalam masalah besar.Anda bisa menggunakan fungsi eval yang menyelesaikan dalam contoh ini variabel jaring sebelum awk dijalankan.
sumber