How do I split a string on a delimiter in Bash?

后端 未结 30 1687
萌比男神i
萌比男神i 2020-11-21 04:58

I have this string stored in a variable:

IN=\"bla@some.com;john@home.com\"

Now I would like to split the strings by ; delimite

相关标签:
30条回答
  • 2020-11-21 05:36

    How about this approach:

    IN="bla@some.com;john@home.com" 
    set -- "$IN" 
    IFS=";"; declare -a Array=($*) 
    echo "${Array[@]}" 
    echo "${Array[0]}" 
    echo "${Array[1]}" 
    

    Source

    0 讨论(0)
  • 2020-11-21 05:36

    This is the simplest way to do it.

    spo='one;two;three'
    OIFS=$IFS
    IFS=';'
    spo_array=($spo)
    IFS=$OIFS
    echo ${spo_array[*]}
    
    0 讨论(0)
  • 2020-11-21 05:37

    If you don't mind processing them immediately, I like to do this:

    for i in $(echo $IN | tr ";" "\n")
    do
      # process
    done
    

    You could use this kind of loop to initialize an array, but there's probably an easier way to do it. Hope this helps, though.

    0 讨论(0)
  • 2020-11-21 05:37

    Here is a clean 3-liner:

    in="foo@bar;bizz@buzz;fizz@buzz;buzz@woof"
    IFS=';' list=($in)
    for item in "${list[@]}"; do echo $item; done
    

    where IFS delimit words based on the separator and () is used to create an array. Then [@] is used to return each item as a separate word.

    If you've any code after that, you also need to restore $IFS, e.g. unset IFS.

    0 讨论(0)
  • 2020-11-21 05:37

    Maybe not the most elegant solution, but works with * and spaces:

    IN="bla@so me.com;*;john@home.com"
    for i in `delims=${IN//[^;]}; seq 1 $((${#delims} + 1))`
    do
       echo "> [`echo $IN | cut -d';' -f$i`]"
    done
    

    Outputs

    > [bla@so me.com]
    > [*]
    > [john@home.com]
    

    Other example (delimiters at beginning and end):

    IN=";bla@so me.com;*;john@home.com;"
    > []
    > [bla@so me.com]
    > [*]
    > [john@home.com]
    > []
    

    Basically it removes every character other than ; making delims eg. ;;;. Then it does for loop from 1 to number-of-delimiters as counted by ${#delims}. The final step is to safely get the $ith part using cut.

    0 讨论(0)
  • 2020-11-21 05:39
    IN='bla@some.com;john@home.com;Charlie Brown <cbrown@acme.com;!"#$%&/()[]{}*? are no problem;simple is beautiful :-)'
    set -f
    oldifs="$IFS"
    IFS=';'; arrayIN=($IN)
    IFS="$oldifs"
    for i in "${arrayIN[@]}"; do
    echo "$i"
    done
    set +f
    

    Output:

    bla@some.com
    john@home.com
    Charlie Brown <cbrown@acme.com
    !"#$%&/()[]{}*? are no problem
    simple is beautiful :-)
    

    Explanation: Simple assignment using parenthesis () converts semicolon separated list into an array provided you have correct IFS while doing that. Standard FOR loop handles individual items in that array as usual. Notice that the list given for IN variable must be "hard" quoted, that is, with single ticks.

    IFS must be saved and restored since Bash does not treat an assignment the same way as a command. An alternate workaround is to wrap the assignment inside a function and call that function with a modified IFS. In that case separate saving/restoring of IFS is not needed. Thanks for "Bize" for pointing that out.

    0 讨论(0)
提交回复
热议问题