如何在bash脚本中拆分字符串

时间:2013-09-27 19:11:27

标签: string bash

尝试将字符串的某些部分提取到变量中。初始字符串如下所示:/dev/sdc2: LABEL="PAKAGE" UUID="9501DCBF768CEBB9" TYPE="ntfs" 我得到了正确的PORTLABE L值,但无法得到其余的值:UUIDTYPE。而不是他们,我只得到它的一部分。

#!/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

我哪里错了?

5 个答案:

答案 0 :(得分:3)

我认为用regexp做得更好。

#!/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

输出:

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

基于this

答案 1 :(得分: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'

答案 2 :(得分: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

答案 3 :(得分: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

答案 4 :(得分:0)

没有eval,但使用的逻辑相同:

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