2013-01-31 64 views
8

我在数组中的以下数据:猛砸分割字符串

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

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

例子:

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

我可以用awk完成这件事:

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

这需要删除尾随空格,看起来复杂。

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

回答

15

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

file=$(echo "${MY_ARR[1]}" | cut -d' ' -f1) 
parameter=$(echo "${MY_ARR[1]}" | cut -d' ' -f2-) 
  • -f1意味着第一个参数。
  • -f2-意味着从第二个参数的一切。
+0

是的,我知道切割。我第一次尝试使用它。我拒绝使用它,因为如果是空格,我害怕错过第三个和第三个结局......需要检查! – idobr

5

您可以使用read

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

这是更好的解决方案,因为它不需要多个新流程来完成任务(一个用于命令替换,两个用于管道任一侧)。 – chepner

2

鉴于此阵:

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

让我们做了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'" 

如何访问各种文件:

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

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

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

    done 

输出:

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 

如何访问每个参数:

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

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

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

    done 

输出:{!MY_FILES [*]}

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 

因为$导致您可以使用相同的索引号访问其他数组,在数组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 
    ) 

输出:

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

除非我失去了一些东西,最简单,最简便的方式是只用扩张的两个变化这一点。

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

说明

  • "${MY_ARR[0]%%' '*}" - 这将删除后的第一空间和东西,然后返回剩余部分
  • "${MY_ARR[0]#*' '}" - 这消除一切到第一空间,并返回剩余部分

有关更详细的说明,请参阅Parameter Expansion部分bash手册页