2014-09-21 23 views
0

actlist文件包含大約15條記錄。我想打印/存儲變量中的每一行以執行進一步的操作。腳本運行但echo $ j顯示空白值。什麼是問題? 我的腳本:awk在變量中的用法

#/usr/bin/sh 

acList=/root/john/actlist 

Rowcount=`wc -l $acList | awk -F " " '{print $1}'` 

for ((i=1; i<=Rowcount; i++)); do 

j=`awk 'FNR == $i{print}' $acList` 

echo $j 
done 

文件:actlist

cat > actlist 

5663233332 2223 2 
5656556655 5545 5 
4454222121 5555 5 
. 
. 
. 
+0

您可以使用'行數= $(WC -l <​​$ aclist)'代替,如果你提供它'像stdin'的文件'wc',它不會告訴你文件名(因爲它不知道它),然後你不需要'awk'來刪除文件名。 – 2014-09-21 18:52:46

+0

問題是您使用shell來操作文本而不是UNIX文本操作工具awk。 shell是一個可以調用工具的環境,就是這樣。 – 2014-09-21 21:53:25

回答

0

問題恰好是相關報價和外殼插值變量的方式。

更具體地講,當你寫

j=`awk "FNR == $i{print}" $acList` 

的AWK代碼必須括入雙引號。如果您希望shell能夠用存儲在i變量中的實際值替換$i,則這是必需的。

在另一方面,如果你寫

j=`awk 'FNR == $i{print}' $acList` 

即與單引號,則$i將被解釋爲一個字符串。

因此,固定代碼將讀取:

#/usr/bin/sh 

acList=/root/john/actlist 

Rowcount=`wc -l $acList | awk -F " " '{print $1}'` 

for ((i=1; i<=Rowcount; i++)); do 

    j=`awk "FNR == $i{print}" $acList` 

    echo $j 
done 

記住:它始終是不變量插值調用的其它命令之前,殼。

話雖如此,在提供的代碼中有一些地方可以設計一些改進。但這是另一回事。

+0

上面有很多問題,包括:不要使用tick來調用shell工具,總是引用shell變量,不要使用無向wc,然後去掉文件名,不要在awk腳本中使用雙引號,使用-v將shell變量值傳遞給awk,不要使用shell來操作文本。 – 2014-09-21 21:56:28

0

我想你也許會用這個工作做好,解析您的文件:

#!/bin/bash 
while read a b c; do 
    echo $a, $b, $c 
done < "$actlist" 

輸出:

5663233332, 2223, 2 
5656556655, 5545, 5 
4454222121, 5555, 5 

更新

雖然上面演示了概念我正在建議,正如@ EdMorton在評論部分所說的那樣正確對於生產環境來說,代碼會更加健壯。

#!/bin/bash 
while IFS= read -r a b c; do 
    echo "$a, $b, $c" 
done < "$actlist" 
+0

如果輸入文件包含通配符字符,反斜槓等,或者其名稱包含空格(以及其他字符?),那麼對於發佈的輸入,如果輸入文件包含通配符字符,反斜槓等,那麼會以有趣的方式失敗。你需要把它寫成'while IFS = read -r a b c;做回聲「$ a,$ b,$ c」;完成<「$ actlist」'是相當健壯的。 – 2014-09-21 22:12:50

0

不幸的是所有的腳本做是打印輸入文件的內容,所以我們不能幫你找出正確的方法做什麼是你真的想沒有更多的信息做什麼是但沒準這是正確的起點:

acList=/root/john/actlist 
awk ' 
{ print } 
' "$acList"