在awk命令中传递参数不会起作用

时间:2016-11-10 16:01:20

标签: bash awk terminal

我用./command script.sh 11运行脚本,第一行代码将输出(321)成功存储在参数x中(在第2行用echo检查)。在第3行,我尝试使用参数x来检索所有行中的最后两列,其中第一列中的值等于x(在doc2.csv中)。这不会起作用,但当我将z=$x替换为z=321时,它可以正常工作。传递参数时,为什么不能使用此代码?

#!/bin/bash
x="$(awk -v y=$1  -F\; '$1 == y' ~/Documents/doc1.csv | cut -d ';' -f2)"
echo $x
awk -v z=$x -F, '$1 == z' ~/Documents/doc2.csv | cut -d ',' -f2,3

doc1.csv(所有列都有唯一值)

33;987
22;654
11;321
...

doc2.csv

321,156843,ABCD
321,637253,HYEB
123,256843,BHJN
412,486522,HDBC
412,257843,BHJN
862,256843,BHLN
...

1 个答案:

答案 0 :(得分:0)

就像其他人提到的那样,你可能会在切割命令的第2场中出现一些额外的角色。

如果您只是使用awk打印您想要的列而不是整行并切割,那么您应该没有任何问题。如果您仍然这样做,则需要查看dos2unix

n=33;
x=$(awk -v y=$n  -F\; '$1 == y {print $2}' d1);
echo ${x};
awk -v z=$x -F, '$1 == z' d2

d1d2包含您概述的doc1和doc2内容。

正如你所看到的,我所做的就是停止在awk的输出上使用cut,如果第一个字段等于输入变量,就告诉awk打印第二个字段。

顺便说一句,如果你不知道awk非常强大......你可以在awk中完成整个程序。

n=11; awk -v x=$n -F\; 'NR==FNR{ if($1==x){ y[$2]; } next}  $1 in y{print $2, $3}' d1 <( sed 's/,/;/g' d2)

NR==FNR这是一个有效说“如果我们仍然在第一个文件中,请执行此操作”的技巧......关键是不要忘记使用next跳过其余的awk命令。一旦我们到达第二个文件FNR翻转回1但NR一直递增,所以它们永远不会再相等。

因此,对于第一个文件,我们只是将第二列值加载到一个数组中,其中第一列与我们传递的变量匹配。您可以对此进行优化,因为您说d1始终是唯一的行。

因此,一旦我们进入下一个文件,逻辑将跳过所有内容并运行$1 in y。这只是检查第一列是否在我们创建的数组中。如果是awk则打印第2列和第3列。

<( sed 's/,/;/g' d2)只是意味着我们希望将sed命令的输出视为文件。 sed命令只是将d2中的逗号转换为分号,以便它与awk期望的FS匹配。

希望您已经了解了一些关于awk的知识,请在此处阅读更多http://www.catonmat.net/blog/ten-awk-tips-tricks-and-pitfalls/,并在此处提供了一个很棒的重定向备忘单http://www.catonmat.net/download/bash-redirections-cheat-sheet.pdf