2014-01-07 141 views
2

我一直在bash中努力解析並將參數文件讀入多個gobal變量。我們同時運行HPUX和Linux環境,並試圖在BASH中實現這一目標。目前它給我在sed語句上的錯誤。即使當我取出sed時,在循環內部它會讀取變量,但只要我退出循環,值就會恢復爲全局定義。已經嘗試在文件的頂部添加「#!/ bin/sh」,但是這不起作用,就像HP8系統一樣。任何幫助,將不勝感激!BASH腳本:從1行文件讀入多個全局變量

set -xv 

ReadStat() { 
set -xv 

while read EngName AllTabs Distribs DropDist BlockSet BlockExp BlockBy MaxProcs ; do 
    echo "read: EngName=$EngName AllTabs=$AllTabs Distribs=$Distribs DropDist=$DropDist BlockSet=$BlockSet BlockExp=$BlockExp BlockBy=$BlockBy MaxProcs=$MaxProcs " 
done < sed -e "s/||/|-|/g" -e "s/||/|-|/g" -e "s/||/|-|/g" -e "s/|/ /g" $StatFile 

#cat $StatFile |\ 
# sed -e "s/||/|-|/g" -e "s/||/|-|/g" -e "s/||/|-|/g" |\ 
# sed -e "s/|/ /g" |\ 
# read EngName AllTabs Distribs DropDist BlockSet BlockExp BlockBy MaxProcs 

} 

# main() { 


BaseNameIs=`basename $0 '.sh'` 

StatFile=/tmp/kz.stat 

EngName="it1xxx" 
CronJob='Y' 
Distribs='B' 
DropDist='N' 
AllTabs='N' 
BlockSet='N' 
# BlockExp=`date '+%Y%m%d%H%M'` 
BlockExp=`date '+%Y%m%d'`'0000' 
BlockBy='none' 
MaxProcs=30 

MyHost=`hostname` 

ReadStat 

# main() } 

輸入文件的樣子:

it1xxx|Y|B|N|Y|201401071110|none|30| 
+1

任何你想跳過BASH並使用Perl的機會? 'split(分割)'會在這樣的單線程上創造奇蹟......'我的($ EngName,$ CronJob,$ Distribs,$ DropDist,$ AllTabs,$ BlockSet,$ BlockExp,$ BlockBy,$ MaxProcs,$ MyHost) = split('|',$ lineIn); $ MyHost = defined($ MyHost)?$ MyHost:\'hostname \''... – abiessu

+1

是不是他的第一個3'-e's在你的'sed -e「s/||/| - |/g 「-e」s/||/| - |/g「-e」s/||/| - |/g「-e」s/|// g「$ StatFile'重複?你只需要其中的一個,因爲你使用的是'g'。哦,當然,將'sed ..'送入重定向('<'),將需要進程替換,即。 '而...;完成<(sed ....)'或者<<(sed ...)'。或者移動sed以通過前面的管道餵食,'sed ... |雖然......「祝你好運。 – shellter

+0

實際上,如果文件沒有值,則會出現這些文件。即使在全球範圍內,|||只會由第一位替補人員來固定,第二位替補人員會在第二位替補人員進入。第三個可能是多餘的。 – user3170886

回答

2

的問題是,雖然循環通常在自己的子shell中運行。可能最直接的解決方案是將輸出保存到臨時文件中,然後輸入臨時文件。

這是一個網頁,說明一些解決方案。 fvue.nl wiki page

1
#! /bin/sh 

vars=("x" "b") 

input_file=`mktemp` 

echo 'foo|bar|' >> $input_file 

Read() { 
    cnt=`cat foo | sed 's/[^|]//g' | wc -c` 
    cnt=$((cnt - 1)) # because the trailing "|" 

    for i in `seq 1 $cnt`; do 
     j=$(($i - 1)) 
     eval "${vars[$j]}=`cat $input_file | cut -f $i -d "|"`" 
    done 

} 

Read 

echo $x 
echo $b 
+0

謝謝大家! IFS的第一個選項工作得很好! (){ IFS ='|'讀-r $ vars dummy <$ StatFile } – user3170886

5

bash的read命令可以處理這個問題:

vars="EngName AllTabs Distribs DropDist BlockSet BlockExp BlockBy MaxProcs" 
IFS='|' read -r $vars dummy < kz.stat 
for var in $vars; do echo "$var = ${!var}"; done 
EngName = it1xxx 
AllTabs = Y 
Distribs = B 
DropDist = N 
BlockSet = Y 
BlockExp = 201401071110 
BlockBy = none 
MaxProcs = 30 

這是至關重要的報價$vars同時在讀取和命令。

+0

不錯。今天Totaly忘記了IFS技巧。您需要eval而不是echo來設置變量以供進一步使用。 – yaccz

+0

任何地方都不需要評估。回聲僅僅是爲了證明變量已經被讀命令正確設置。 –