Dividindo string pela primeira ocorrência de um delimitador

41

Eu tenho uma string no próximo formato

id;some text here with possible ; inside

e deseja dividi-lo em 2 strings pela primeira ocorrência do ; . Portanto, deve ser: id e some text here with possible ; inside

Eu sei dividir a string (por exemplo, com cut -d ';' -f1 ), mas ela será dividida em mais partes, pois eu tenho ; dentro da parte esquerda.

    
por gakhov 30.10.2012 / 14:03

5 respostas

56

cut soa como uma ferramenta adequada para isso:

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

Mas read é ainda mais adequado:

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
    
por 30.10.2012 / 14:33
16

Com qualquer padrão sh (incluindo bash):

sep=';'
case $s in
  (*"$sep"*)
    before=${s%%"$sep"*}
    after=${s#*"$sep"}
    ;;
  (*)
    before=$s
    after=
    ;;
esac
As soluções baseadas em

read funcionariam para valores de caractere único (e com alguns shells, byte único) de $sep diferentes de espaço, tabulação ou nova linha e somente se $s não contiver caracteres de nova linha.

As soluções baseadas em

cut só funcionam se $s não contiver caracteres de nova linha.

sed soluções poderiam ser criadas para lidar com todos os casos de canto com qualquer valor de $sep , mas não vale a pena ir tão longe quando houver suporte embutido no shell para isso.

    
por 30.10.2012 / 15:35
5

Como você mencionou, deseja atribuir os valores a id e string

primeiro atribua seu padrão a uma variável (digamos, str)

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

Agora você tem seus valores nas respectivas variáveis

    
por 31.10.2012 / 13:18
4

Além das outras soluções, você pode tentar algo com base em regex :

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

ou dependendo do que você está tentando fazer exatamente, você pode usar

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

onde e contêm os dois substrings que você estava querendo.

    
por 30.10.2012 / 15:17
1

Solução no bash padrão:

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

    echo $text1
    #=> id;
    echo $text2
    #=> some text here with possible ; insideDD
    
por 05.10.2018 / 17:57