我用./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
...
答案 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
d1
和d2
包含您概述的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。