2016-11-10 55 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