如何将一系列模式从 shell 脚本传递到 awk 中?

如何将一系列模式从 shell 脚本传递到 awk 中?

我存储了一系列模式foo.txt,我想迭代这些模式并查看 file 中的哪些匹配行bar.txt

while read PWW
do
   cat user/dump/bar.txt | awk '/${PWW}/{print $2}' >> user/dump/out.txt
done < user/dump/foo.txt

foo.txt:

2100001b32
2100001b38
3100001b35
4100001b28
5100001b46
6100001b56

bar.txt:

2100001b32 good
2100001b38 bad
3100001b35 okay
4100001b28 large
5100001b46 good
6100001b56 bad

期望out.txt

good
bad
okay
large
good
bad

我无法搜索 中的值foo.txt。 while 循环运行并给我空输出。我想是awk在寻找${PWW}(字面意思)而不是它的值foo.txt

我怎样才能让它发挥作用?我的环境是Solaris 5.10,使用Korn shell,带有basic awk (旧awk)。

答案1

这是一个纯 awk 解决方案:

$ awk 'FNR==NR{a[$1]=$2; next} {print a[$1]}' bar.txt foo.txt
good
bad
okay
large
good
bad

怎么运行的

该脚本首先读取 bar.txt 并将其信息保存在 array 中a。然后它读取 foo.txt 并打印出相应的值。

  • FNR==NR{a[$1]=$2; next}

    FNR 是从当前文件读取的行数,NR 是迄今为止读取的总行数。因此,如果FNR==NR,我们仍在读取第一个文件 (bar.txt)。如果是,a[$1]=$2则用于向a保存这些值的数组添加一个条目。然后,我们跳过脚本中的其余命令并重新开始next

  • print a[$1]

    如果我们到达这里,我们正在读取第二个文件 foo.txt。我们逐行读取 foo.txt。对于每一行,我们查找与第一列中的键对应的值并打印它。

答案2

检查你的报价。在包括 bash 在内的 unix shell 中:单引号将未修改的文本传递给程序(正如您所说的 pass ${PWW},双引号允许变量扩展。

在您的示例中,您想要${PWW}扩展但不想扩展$2,您可以这样做:

awk "/${PWW}/"'{print $2}'
awk /${PWW}/{print '$2'}
awk "/${PWW}/{print \$2}"

答案3

将字符串值从 shell 传递到其中的规范方法awk是通过-v var=val选项。

如果您想使用这些字符串进行模式匹配(传统上使用 )/.../,您需要针对整行编写显式匹配:

awk -v pattern=${PWW} '$0 ~ pattern {print $2}'

BTW,对于 Solaris 10,nawk建议使用普通旧版本awk,如果只是为了比普通版本更好的错误消息"bailing out at ..."

相关内容