Unix

While循環從grep讀取多行

  • October 12, 2012

我正在 AIX 5.3 中編寫一個腳本,它將遍歷 a 的輸出df並根據另一個配置文件檢查每個卷。如果卷出現在配置文件中,它將設置腳本稍後需要的標誌。如果我的配置文件只有一列並且我使用for循環,那麼這非常有效。然而,我的問題是,如果我使用while read循環在每行填充多個變數,那麼我在 thewhile和 the之間設置的任何變數done都將被丟棄。

例如,假設 /netapp/conf/ExcludeFile.conf 的內容是一堆包含兩個欄位的行:

volName="myVolume"
utilization=70
thresholdFlag=0

grep volName /netapp/conf/ExcludeFile.conf | while read vol threshold; do
   if [ $utilization -ge $threshold ] ; then
       thresholdFlag=1
   fi
done

echo "$thresholdFlag"

在此範例中,thresholdFlag 將始終為 0,即使該卷出現在文件中並且其使用率大於門檻值。我可以echo "setting thresholdFlag to 1"在那裡添加一個,看到迴聲,它仍然會在最後回顯一個 0。

有沒有一種干淨的方法可以做到這一點?我認為我的 while 循環是在一個子 shell 中完成的,並且我對其中的變數所做的更改實際上是對在done.

Zoredache 在聊天中向我指出了這一點,poige 在他的回答中提到了這一點:這個問題可以通過 subshel​​l 解決。

當我不得不從一次for從我的 grep 讀取單個變數的循環更改為while read var1 var2允許我讀取多個變數的循環時,我能夠通過使用括號來保留我在 while 循環中操作的臨時變數定義一個顯式的子shell。這是一個例子:

sum=0

grep volume configfile | head -n1 | (while read var1 var2; do
 let sum=var1+var2
done

echo "The sum is $sum.")

沒有括號,您將始終回顯總和 0。使用它們,您將回顯 grep 的第一個匹配行中的前兩個值的總和。

此外,正如 Poige 在另一個答案中指出的那樣,您可以使用子外殼來填充範圍內的變數,如下所示:

var=$( cat file | while read a b; do
   sum=a+b
   echo "$sum"
done)

echo "$var"

在這種情況下,您在最後回顯的 var 的值將是您在循環中計算的最後一個總和,即使 sum 在子外殼的末尾被破壞。

引用自:https://serverfault.com/questions/437484