通过第一次出现的分隔符分割字符串


54

我有以下格式的字符串

id;some text here with possible ; inside

并希望在第一次出现时将其拆分为2个字符串;。因此,应为:idsome text here with possible ; inside

我知道如何分割字符串(例如,使用cut -d ';' -f1),但是由于我;位于左侧,因此它将分割为更多部分。


字符串拆分后,您要如何使用“ id”?您是否要将其分配给变量,将其打印出来等?
混沌守护进程2012年

我将有2个变量:idstring
gakhov 2012年

Answers:


65

cut 听起来像是一个合适的工具:

bash-4.2$ s='id;some text here with possible ; inside'

bash-4.2$ id="$( cut -d ';' -f 1 <<< "$s" )"; echo "$id"
id

bash-4.2$ string="$( cut -d ';' -f 2- <<< "$s" )"; echo "$string"
some text here with possible ; inside

但是read更合适:

bash-4.2$ IFS=';' read -r id string <<< "$s"

bash-4.2$ echo "$id"
id

bash-4.2$ echo "$string"
some text here with possible ; inside

3
大!它就像一个魅力!我将选择,read因为我正在使用bash。谢谢@manatwork!
gakhov 2012年

cut方法仅在“ $ s”不包含换行符时才有效。在任何类似Bourne的外壳中都可以读取。<<<在rc,zsh以及bash和ksh93的最新版本中,并且是非标准版本。
斯特凡Chazelas

糟糕,您是正确的@StephaneChazelas。当时我就-a提的,当由于某种原因bashread。(显然这里没有用。)
manatwork

我忘了提一下,如果$ s包含换行符,则读取方法也不起作用。我已经添加了自己的答案。
斯特凡Chazelas

1
我想强调-f 2-一下string="$( cut -d ';' -f 2- <<< "$s" )"; echo "$string"命令中的后划线。这就是忽略打印输出字符串中其余定界符的原因。在查看cut
Steen

17

使用任何标准sh(包括bash):

sep=';'
case $s in
  (*"$sep"*)
    before=${s%%"$sep"*}
    after=${s#*"$sep"}
    ;;
  (*)
    before=$s
    after=
    ;;
esac

read基于解决方案的解决方案$sep仅适用于空格,制表符或换行符以外的单个字符(并带有一些shell,单个字节)的值,并且仅适用于$s不包含换行符的情况。

cut基于解决方案的解决方案仅在$s不包含换行符的情况下才有效。

sed可以设计出解决方案,以任何值处理所有极端情况$sep,但是,如果外壳中内置了对此的支持,那么就不值得这样做了。


6

如前所述,您想将值分配给idstring

首先将模式分配给变量(例如str)

    str='id;some text here with possible ; inside'
    id=${str%%;} 
    string=${str#;}

现在,您在各自的变量中有了值


如果您从命令中获取模式,然后使用 some_command
set-

这个答案与@StephaneChazelas有什么不同?
Bernhard

4

除了其他解决方案,您还可以尝试以下regex方法:

a="$(sed 's/;.*//' <<< "$s")"
b="$(sed 's/^[^;]*;//' <<< "$s")"

或根据您要确切执行的操作,可以使用

sed -r 's/^([^;]*);(.*)/\1 ADD THIS TEXT BETWEEN YOUR STRINGS \2/'

在那里\1,并\2包含你想两个子。


1

标准bash解决方案:

    text='id;some text here with possible ; inside'
    text2=${text#*;}
    text1=${text%"$text2"}

    echo $text1
    #=> id;
    echo $text2
    #=> some text here with possible ; insideDD
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.