简体   繁体   English

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

[英]How to split a string in bash script

Trying to extract some parts of a string into variables. 尝试将字符串的某些部分提取到变量中。 Initial string looks like this: /dev/sdc2: LABEL="PAKAGE" UUID="9501DCBF768CEBB9" TYPE="ntfs" I getting correct PORT and LABE L values, but cant get the rest: UUID and TYPE . 初始字符串如下所示: /dev/sdc2: LABEL="PAKAGE" UUID="9501DCBF768CEBB9" TYPE="ntfs"我得到正确的PORTLABE L值,但无法获取其余值: UUIDTYPE Instead of them I getting just a piece of it. 我没有得到它们的一部分。

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

Where am I wrong? 我哪里错了?

I think it's better done with regexp. 我认为使用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

Output: 输出:

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

Based on this . 基于

This uses eval and is therefore risky. 这将使用eval ,因此存在风险。 Ensure you know where your data is coming from. 确保您知道数据来自何处。

$ 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'

Defining patterns over values, instead of keys, isn't the best way to deal with parsing. 在值(而不是键)上定义模式不是处理解析的最佳方法。 You might be better off doing it this way: 您最好这样做:

$ 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

You could resort to simply clearing the string of all the undesirable portions and using read to populate your variables 您可以求助于简单地清除所有不良部分的字符串,然后使用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

Without eval , but same logic using : 没有eval ,但是使用逻辑相同:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM