2013-01-31 17 views
8

diviso ho i seguenti dati in array:Bash stringa

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

voglio dividerlo in due variabili: $file e $parameter.

Esempio:

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

posso farlo con awk:

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

Questo deve rimuovere gli spazi finali e sembra complicato.

C'è un modo migliore per farlo?

risposta

15

Sembra che il separatore tra i campi sia uno spazio. Quindi, è possibile utilizzare cut per dividerli:

file=$(echo "${MY_ARR[1]}" | cut -d' ' -f1) 
parameter=$(echo "${MY_ARR[1]}" | cut -d' ' -f2-) 
  • -f1 significa che il primo parametro.
  • -f2- significa tutto dal secondo parametro.
+0

sì, so di taglio. L'ho usato con il mio primo tentativo. Mi sono rifiutato di usarlo perché avevo paura di perdere il terzo e il fouth fieleds se gli spazi sono ... Devo controllare! – idobr

5

È possibile utilizzare read:

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

Questa è la soluzione migliore, poiché non richiede più nuovi processi per eseguire l'attività (uno per la sostituzione di comando, due per entrambi i lati della pipeline). – chepner

2

Data questa matrice:

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 fare 2 nuovi array My_Files e 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'" 

Come accedere ogni 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 

uscita:

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 

Come accedere ogni parametro:

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

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

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

    done 

uscita: {! 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 

Dal $ risultati nel indice NUMBER di array MY_FILES puoi anche utilizzare gli stessi numeri di indice per accedere agli altri array. In t A suo modo, è possibile accedere a più colonne di dati nello stesso ciclo. In questo modo:

################ 
    # 
    # 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 
    ) 

uscita:

      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

A meno che non mi manca qualcosa, più semplice e più portatile sarebbe di utilizzare solo due varianti di espansione per questo.

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

Spiegazione

  • "${MY_ARR[0]%%' '*}" - Questo rimuove il primo spazio e tutto ciò dopo che, e torna restante parte
  • "${MY_ARR[0]#*' '}" - Questo elimina tutto ciò che fino al primo spazio, e restituisce il restante parte

Per una spiegazione più dettagliata, vedere la Parameter Expansion sezione della pagina man bash