2009-11-30 27 views
5
#!/bin/bash 

for ((var=0; var<20; var++)) 
do 
echo " Number is: $(grep 'Multiple_Frame = echo **$var**' 20mrf.txt | wc -l)" >>statisic.txt 

done 

該外殼程序不能產生正確的結果,其可能錯誤變量在第二grep命令返回的原因。如何在shell程序中grep一個變量?

如何在第二個echo語句中grep一個變量?根據變化來改變不同的東西?

非常感謝!

回答

4

正如其他人所說,問題是單引號會阻止變量的擴展。但是,使用$()允許你使用雙引號:雖然我懷疑這樣的事情

echo " Number is: $(grep "Multiple_Frame = echo **$var**" 20mrf.txt | wc -l)" >>statisic.txt 

是你的意思:

echo " Number is: $(grep "Multiple_Frame = $var" 20mrf.txt | wc -l)" >>statisic.txt 

你也應該知道,grep有一個選項可以輸出算上這樣你就可以省略wc

echo " Number is: $(grep -c "Multiple_Frame = $var" 20mrf.txt)" >>statisic.txt 
1

您必須將每個替換存儲在一個變量中。就像這樣:

#!/bin/bash 

for ((var=0; var < 20; var++)) 
do 

count=`grep "Multiple_Frame = $var" 20mrf.txt | wc -l` 
echo " Number is: $count" >> statisic.txt 

done
+0

當我按照你告訴我的方式拆分命令後,我得到以下錯誤信息。 ./loop_count_reference_frame_no.sh:第10行:grep「Multiple_Frame = $ var」20mrf.txt | wc -l:command not found – MaiTiano 2009-11-30 07:05:42

+0

也許單引號無法生成正確的grep結果並將其發送到新的「count」變量。 – MaiTiano 2009-11-30 07:07:07

+0

我知道什麼是錯誤的地方...我應該使用esc不是簡單的單引號。不管怎麼說,還是要謝謝你。 – MaiTiano 2009-11-30 14:24:44

0

裏面的字符串$(...)的報價單引號('...')此引用防止變量擴展。改用雙引號。你的情況:

#!/bin/bash 

for ((var=0; var<20; var++)) 
do 
echo " Number is: $(grep 'Multiple_Frame = echo **'"$var"'**' 20mrf.txt | wc -l)" >>statisic.txt 

done 

注意,在這個例子中,它似乎是爲echo命令的雙引號已經打開,但你應該注意的是,$(...)首先計算,並沒有在它裏面沒有雙引號。因此,此處的更改是關閉grep開放雙引號的單引號,然後關閉雙引號並稍後重新打開單引號。

該冗長的解釋示出打破錶達分開,通過其他的答案所建議的益處。

+0

關閉grep的單引號無法幫助它產生正確的結果。無論如何,謝謝〜 – MaiTiano 2009-11-30 06:50:34

1

好的,第二個[原文如此]問題與您在第5行的引用有關。對$ var的引用永遠不會被展開,因爲它包含在單引號內。您可以通過用雙引號(\")替換單引號(')來解決此問題。

第一個[原文如此]問題是您嘗試在單行中做了太多操作,導致您的引號嵌套問題。將線路分成多個命令,根據需要存儲中間結果。是的,它可能會慢一點,但是您會節省很多時間調試和維護它。

交易者的第二定律:如果您必須選擇性能優化和可維護性優化之間的選擇,請始終選擇讓您的代碼更易於維護。電腦一直在變快;程序員不。

2

@OP,做你做了什麼使得w ay效率不高。你在同一個文件上調用grep和wc 20次。只需打開一次文件,並在文件內容的1次迭代中獲取所需的所有內容。 bash中的示例4。0

declare -A arr 
while read -r line 
do 
    case "$line" in 
     *"Multiple_Frame ="*) 
      line=${line#*Multiple_Frame = } 
      num=${line%% *} 
      if [ -z ${number_num[$num]} ] ;then 
       number_num[$num]=1 
      else 
       number_num[$num]=$((number_num[$num]+1)) 
      fi 
      ;; 
    esac  
done <"file" 
for i in "${!number_num[@]}" 
do 
    echo "Multiple_Frame = $i has ${number_num[$i]} counts" 
done 

同樣,您可以使用gawk中的關聯數組來幫助您完成此任務。

gawk '/Multiple_Frame =/{ 
    sub(/.*Multiple_Frame = /,"") 
    sub(/ .*/,"") 
    arr["Multiple_Frame = "$0]=arr["Multiple_Frame = "$0]+1 
}END{ 
    for(i in arr) print i,arr[i] 
}' file 
+0

OMG,你的程序很棒。 因爲我是這些Linux編程的新手,你真的給了我一個很好的教訓。 謝謝。〜 – MaiTiano 2009-11-30 07:16:23