string Bash 拆分字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14629121/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 01:47:30  来源:igfitidea点击:

Bash split string

stringbashawksplitcut

提问by idobr

I have the following data in array:

我在数组中有以下数据:

MY_ARR[0]="./path/path2/name.exe 'word1 word2' 'name1,name2'" 
MY_ARR[1]="./path/path2/name.exe 'word1 word2' 'name3,name4,name5'"
MY_ARR[2]=".name.exe 'word1 word2'"
MY_ARR[3]="name.exe"
MY_ARR[4]="./path/path2/name.exe 'word1 word2' 'name1'"
MY_ARR[5]="./path/path2/name.exe 'word1 word2' 'name.exe, name4.exe, name5.exe'"

I want to divide it into two variables: $fileand $parameter.

我想把它分成两个变量:$file$parameter

Example:

例子:

file="./path/path2/name.exe"
parameter="'word1 word2' 'name1,name2'"

I can do it with awk:

我可以用 awk 做到:

parameter=$(echo "${MY_ARR[1]}" | awk -F\' '{print  }')
file=$(echo "${MY_ARR[1]}" | awk -F\' '{print }')

This needs to remove trailing spaces and looks to complicated.

这需要删除尾随空格并且看起来很复杂。

Is there a better way to do it?

有没有更好的方法来做到这一点?

回答by fedorqui 'SO stop harming'

It looks like the separator between the fields is an space. Hence, you can use cutto split them:

看起来字段之间的分隔符是一个空格。因此,您可以使用cut拆分它们:

file=$(echo "${MY_ARR[1]}" | cut -d' ' -f1)
parameter=$(echo "${MY_ARR[1]}" | cut -d' ' -f2-)
  • -f1means the first parameter.
  • -f2-means everything from the second parameter.
  • -f1表示第一个参数。
  • -f2-表示第二个参数中的所有内容。

回答by Thor

You can use read:

您可以使用read

$ read file parameter <<< ${MY_ARR[1]}
$ echo "$file"
./path/path2/name.exe
$ echo "$parameter"
'word1 word2' 'name3,name4,name5'

回答by Zhoul

Given this array:

鉴于此数组:

    MY_ARR[0]="./path/path2/name.exe 'word1 word2' 'name1,name2'"
    MY_ARR[1]="./path/path2/name.exe 'word1 word2' 'name3,name4,name5'"
    MY_ARR[2]=".name.exe             'word1 word2'"
    MY_ARR[3]="name.exe"
    MY_ARR[4]="./path/path2/name.exe 'word1 word2' 'name1'"
    MY_ARR[5]="./path/path2/name.exe 'word1 word2' 'name.exe, name4.exe, name5.exe'"

Lets make 2 new arrays MY_FILES and MY_PARAMETERS

让我们创建 2 个新数组 MY_FILES 和 MY_PARAMETERS

    for  MY_ARR_INDEX in  ${!MY_ARR[*]}  ;  do

         ######
         # Set the current file in new array.

              MY_FILES[ ${MY_ARR_INDEX} ]=${MY_ARR[ ${MY_ARR_INDEX} ]// *}

         ######
         # Set the current parameters in new array

         MY_PARAMETERS[ ${MY_ARR_INDEX} ]=${MY_ARR[ ${MY_ARR_INDEX} ]#* }

         ######
         # Show the user whats happening
         # (from here until done is just printing info.)

         printf "MY_FILES[ ${MY_ARR_INDEX} ]=\"%s\"  ;  MY_PARAMETERS[ ${MY_ARR_INDEX} ]=\"%s\"\n" \
         \
          "${MY_ARR[ ${MY_ARR_INDEX} ]// *}"  "${MY_ARR[ ${MY_ARR_INDEX} ]#* }"

    done


    MY_FILES[ 0 ]="./path/path2/name.exe"  ;  MY_PARAMETERS[ 0 ]="'word1 word2' 'name1,name2'"
    MY_FILES[ 1 ]="./path/path2/name.exe"  ;  MY_PARAMETERS[ 1 ]="'word1 word2' 'name3,name4,name5'"
    MY_FILES[ 2 ]=".name.exe"  ;  MY_PARAMETERS[ 2 ]="            'word1 word2'"
    MY_FILES[ 3 ]="name.exe"  ;  MY_PARAMETERS[ 3 ]="name.exe"
    MY_FILES[ 4 ]="./path/path2/name.exe"  ;  MY_PARAMETERS[ 4 ]="'word1 word2' 'name1'"
    MY_FILES[ 5 ]="./path/path2/name.exe"  ;  MY_PARAMETERS[ 5 ]="'word1 word2' 'name.exe, name4.exe, name5.exe'"

How to access each file:

如何访问每个文件:

    for  MY_ARR_INDEX in  ${!MY_FILES[*]}  ;  do

         CUR_FILE=${MY_FILES[ ${MY_ARR_INDEX} ] }

         echo "# Do something with this file: ${CUR_FILE}"

    done

Output:

输出:

    Do something with this file: ./path/path2/name.exe
    Do something with this file: ./path/path2/name.exe
    Do something with this file: .name.exe
    Do something with this file: name.exe
    Do something with this file: ./path/path2/name.exe
    Do something with this file: ./path/path2/name.exe

How to access each parameter :

如何访问每个参数:

    for  MY_ARR_INDEX in  ${!MY_PARAMETERS[*]}  ;  do

         CUR_FILE=${MY_FILES[ ${MY_ARR_INDEX} ]}

         echo "# Do something with this parameter: ${CUR_FILE}"

    done

Output:

输出:

    Do something with this parameter: ./path/path2/name.exe
    Do something with this parameter: ./path/path2/name.exe
    Do something with this parameter: .name.exe
    Do something with this parameter: name.exe
    Do something with this parameter: ./path/path2/name.exe
    Do something with this parameter: ./path/path2/name.exe

Since ${!MY_FILES[ [*]} results in the index NUMBERS of array MY_FILES you can also use the same index numbers to access the other arrays.In this way, you may access multiple columns of data in the same loop. Like so:

由于 ${!MY_FILES[[*]} 导致数组 MY_FILES 的索引号为 NUMBERS,您也可以使用相同的索引号访问其他数组。这样,您可以在同一个循环中访问多列数据。像这样:

    ################
    #
    # Print each file and matching parameter(s)
    #
    ################

    # Set a printf format string so we can print all things nicely.

    MY_PRINTF_FORMAT="#  %25s  %s\n"

    ################
    #
    # Print the column headings and use index numbers
    #
    #        to print adjacent array elements.
    #
    ################
    (

            printf   "${MY_PRINTF_FORMAT}"  "FILE" "PARAMETERS"    "----" "----------"

        for  MY_ARR_INDEX in  ${!MY_FILES[*]}  ;  do

             printf  "${MY_PRINTF_FORMAT}"  "${MY_FILES[ ${MY_ARR_INDEX} ]}"  "${MY_PARAMETERS[ ${MY_ARR_INDEX} ]}"

        done
    )

Output :

输出 :

                           FILE  PARAMETERS
                           ----  ----------
          ./path/path2/name.exe  'word1 word2' 'name1,name2'
          ./path/path2/name.exe  'word1 word2' 'name3,name4,name5'
                      .name.exe              'word1 word2'
                       name.exe  name.exe
          ./path/path2/name.exe  'word1 word2' 'name1'
          ./path/path2/name.exe  'word1 word2' 'name.exe, name4.exe, name5.exe'

回答by Reinstate Monica Please

Unless I'm missing something, simplest and most portable way would be to just use two variations of bashexpansion for this.

除非我遗漏了什么,否则最简单和最便携的方法就是为此使用bash扩展的两种变体。

file="${MY_ARR[0]%%' '*}"
parameter="${MY_ARR[0]#*' '}"

Explanation

解释

  • "${MY_ARR[0]%%' '*}"- This removes the first space and anything after it, and returns remaining part
  • "${MY_ARR[0]#*' '}"- This removes everything up to the first space, and returns the remaining part
  • "${MY_ARR[0]%%' '*}"- 这将删除第一个空格及其后的任何内容,并返回剩余部分
  • "${MY_ARR[0]#*' '}"- 这将删除直到第一个空格的所有内容,并返回剩余部分

For a more detailed explanation, see the Parameter Expansionsection of the bash man page

有关更详细的解释,请参阅Parameter Expansionbash 手册页的部分