将bash数组元素传递给awk regex内部循环

时间:2014-08-22 13:55:28

标签: regex bash awk

我正在尝试使用awk搜索文件,循环遍历bash数组的元素。这就是我目前正在做的事情

myarray[1] = 441
myarray[2] = 123

for i in "${myarray[@]}"
do
awk '{if ($4 == '"$i"') print $0}' myfile.txt > newfile.txt
done

是否可以通过这种方式访问​​awk中bash数组的元素?

4 个答案:

答案 0 :(得分:5)

这不是将shell变量(或BASH数组元素)传递给awk的正确方法。与-v选项一起使用:

myarray=(441 123)

for i in "${myarray[@]}'"; do
   awk -v i="$i" '$4 == i' myfile.txt > newfile.txt
done
  • -v i="$i"$i内的shell变量awk用作awk变量i
  • $4 == i相当于{if ($4 == i) print $0},因为print $0是默认操作

答案 1 :(得分:5)

不需要bash循环;你可以用awk完成整个事情:

my_array=(441 123)
awk -varr="${my_array[*]}" 'BEGIN{split(arr,a); for(i in a)b[a[i]]} $4 in b' file

shell数组的内容作为单个字符串传递给awk,每个元素之间有一个空格。 split用于从字符串创建awk数组。数组a如下所示:

a[1]=441; a[2]=123

for循环使用两个键bb[441]创建一个数组b[123]

当第4列与其中一个数组键匹配时,将打印行。

请记住,当数组中的元素包含空格时,此方法会失败。

答案 2 :(得分:2)

您可以避免在外部循环遍历bash数组元素。在下文中,数组元素一次性传递到awk,并使用awkARGV内访问。此外,没有理由awk无法直接写入输出文件

awk -v len="${#myarray[@]}" '
BEGIN{t=ARGC; ARGC-=len; for(i=2; i<t; ++i) b[ARGV[i]]++ };
$4 in b { print > "newfile.txt"}' myfile.txt  "${myarray[@]}"

答案 3 :(得分:0)

你也可以构建一个awk正则表达式:

myarray=(441 123)
regex=$(IFS=\|;echo "^(${myarray[*]})\$")
awk -v regex="$regex" '$4 ~ regex' myfile.txt > newfile.txt

但是,如果在元素中有元字符(即&#39; *&#39;,&#39; \&#39;,&#39;?&#39;等),请务必小心阵列。