2013-09-27 67 views
1

嘗試將字符串的某些部分提取到變量中。初始的字符串看起來是這樣的:/dev/sdc2: LABEL="PAKAGE" UUID="9501DCBF768CEBB9" TYPE="ntfs" 我得到正確PORTLABE的L值,但不能得到休息:UUIDTYPE。而不是他們,我只是獲得了一小部分。如何在bash腳本中拆分字符串

#!/bin/bash 

INDEX1="" 
INDEX2="" 
LENGTH="" 
PORT="" 
LABEL="" 
UUID="" 
TYPE="" 

line=`echo /dev/sdc2: LABEL="PAKAGE" UUID="9501DCBF768CEBB9" TYPE="ntfs" | sed s/\"//g` 
echo $line 

INDEX1=`expr index "$line" /dev/` 
PORT=${line:$INDEX1-1:9} 

INDEX1=`expr index "$line" LABEL=` 
INDEX2=`expr index "$line" UUID` 
INDEX1=`expr $INDEX1 + 5` 
INDEX2=`expr $INDEX2 - 2` 
LABEL=${line:$INDEX1:$INDEX2-$INDEX1} 

INDEX1=`expr index "$line" UUID=` 
INDEX2=`expr index "$line" TYPE` 
INDEX1=`expr $INDEX1 + 4` 
INDEX2=`expr $INDEX2 - 2` 
UUID=${line:$INDEX1:$INDEX2-$INDEX1} 

INDEX1=`expr index "$line" TYPE=` 
INDEX1=`expr $INDEX1 + 4` 
TYPE=${line:$INDEX1} 

echo $PORT 
echo $LABEL 
echo $UUID 
echo $TYPE 


Here the output of this script: 
/dev/sdc2: LABEL=PAKAGE UUID=9501DCBF768CEBB9 TYPE=ntfs 
/dev/sdc2 
PAKAGE 
GE UUID=9501DCBF768CEBB9 T 
KAGE UUID=9501DCBF768CEBB9 TYPE=ntfs 

我在哪裏錯了?

+1

這將是更好/更安全,不會在bash做到這一點在所有:Python的' shlex'模塊(在標準庫中)對於shell語法來說是一個比任何bash內置的任何東西都更好的詞法分析器。否則,你最終會遇到危險的方法(如'eval')或脆弱的方法(如試圖推出自己的解析器)。 –

+0

我不知道蟒蛇不幸的是(和正則表達式) – Chord

回答

3

我認爲使用正則表達式更好。

#!/bin/bash 
src='/dev/sdc2: LABEL="PAKAGE" UUID="9501DCBF768CEBB9" TYPE="ntfs"' 

regex='([^:]+): LABEL="([^"]+)" UUID="([^"]+)" TYPE="([^"]+)"' 

if [[ $src =~ $regex ]]; then 
    echo "matches" 
    i=1 
    n=${#BASH_REMATCH[*]} 
    while [[ $i -lt $n ]] 
    do 
     echo " capture[$i]: ${BASH_REMATCH[$i]}" 
     let i++ 
    done 
else 
    echo "does not match" 
fi 

輸出:基於this

matches 
    capture[1]: /dev/sdc2 
    capture[2]: PAKAGE 
    capture[3]: 9501DCBF768CEBB9 
    capture[4]: ntfs 

+1

一個更通用的正則表達式將是'正則表達式='([^:] +):LABEL = 「([^」] +)」 UUID = 「([^」 ] +)「TYPE =‘([^’] +)」'' - 不承擔約 –

+0

你說得對變量的值什麼,更新了答案 – biomancer

+0

我不認爲它可能適當的正則表達式。不同的分隔符。但它確實工作得很好。非常感謝! – Chord

0

你可以採取簡單地清除所有不需要的部分串並使用read來填充變量

read -r PORT LABEL UUID TYPE <<< "$(echo '/dev/sdc2: LABEL="PAKAGE" UUID="9501DCBF768CEBB9" TYPE="ntfs"' |\ 
sed 's/\(.*\): \+LABEL="\([^"]\+\)" \+UUID="\([^"]\+\)" \+TYPE="\([^"]\+\)"/\1 \2 \3 \4/')" 
echo $PORT 
/dev/sdc2 
echo $LABEL 
PAKAGE 
echo $UUID 
9501DCBF768CEBB9 
echo $TYPE 
ntfs 
+0

我們假定你是有任何變量值的無空格。 –

+0

@glennjackman,你說得對。其實我喜歡你的'eval'更好的解決方案 – iruvar

1

這使用eval,因此是有風險的。確保你知道你的數據來自哪裏。

$ line='/dev/sdc2: LABEL="this is the label" UUID="this is the uuid" TYPE="ntfs"' 
$ IFS=: read port variables <<< "$line" 
$ echo "$port" 
/dev/sdc2 
$ echo "$variables" 
LABEL="this is the label" UUID="this is the uuid" TYPE="ntfs" 
$ eval "$variables" 
$ printf "%s='%s'\n" label "$LABEL" uuid "$UUID" type "$TYPE" 
label='this is the label' 
uuid='this is the uuid' 
type='ntfs' 
1

根據值而不是鍵定義模式不是處理解析的最佳方式。你可能會更好做這種方式:

$ line='/dev/sdc2: LABEL="PAKAGE" UUID="9501DCBF768CEBB9" TYPE="ntfs"' 
$ entry=(${line//\"/}) 

$ PORT=${entry[0]} PORT=${PORT//:/}  # defining variable PORT 
$ declare ${entry[1]}     # defining variable LABEL 
$ declare ${entry[2]}     # defining variable UUID 
$ declare ${entry[3]}     # defining variable TYPE  

$ echo -e "${PORT}\n${LABEL}\n${UUID}\n${TYPE}" 
sdc2: 
PAKAGE 
9501DCBF768CEBB9 
ntfs 
+1

+1該OP需要'的/ dev/sdc2'而不是'SDC2:'雖然 – iruvar

+0

@ 1_CR誤反向工程OP的榜樣!(:謝謝指點出來 – Rubens

+1

你假設有在所列出的值沒有空格 –

0

沒有eval,但使用同樣的邏輯:

$ line=\"/dev/sdc2: LABEL="PAKAGE" UUID="9501DCBF768CEBB9" TYPE="ntfs"\" 
$ echo "${line%% *}" 
/dev/sdc2 
$ echo "$LABEL" 
PAKAGE 
$ echo "$UUID" 
9501DCBF768CEBB9 
$ echo "$TYPE" 
ntfs 
+0

我做沒有得到那個輸出:我看到''/ dev/sdc2:'和'ntfs'' –

+0

增加了'bash'的要求。 –

+0

我在'bash'上獲得了與Glenn Jackman相同的輸出 – iruvar