我正在尝试使用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数组的元素?
答案 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
循环使用两个键b
和b[441]
创建一个数组b[123]
。
当第4列与其中一个数组键匹配时,将打印行。
请记住,当数组中的元素包含空格时,此方法会失败。
答案 2 :(得分:2)
您可以避免在外部循环遍历bash
数组元素。在下文中,数组元素一次性传递到awk
,并使用awk
在ARGV
内访问。此外,没有理由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;等),请务必小心阵列。