2013-09-27 105 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