2016-11-10 57 views
0

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

#!/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 
... 
+2

你为什么使用'cut'?在'awk'中输出你想要的列:''$ 1 == y {print $ 2}''。 – chepner

+2

您的任一个CSV文件是否使用DOS行尾? – chepner

+0

你在第一个文件的每行末尾几乎肯定会有一些空格,所以'x'不是'321'它的'321 ',而@chepner说这很可能是control-Ms,所以运行dos2unix或者首先在文件上类似。另外,当你使用awk时,你永远不需要cut,grep或sed或其他任何小工具。阅读由Arnold Robbins撰写的有效Awk编程,第4版。 –

回答

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的输出,并告诉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