2013-01-31 20 views
8

tôi có các dữ liệu sau trong mảng:Bash chia chuỗi

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

Tôi muốn chia nó thành hai biến: $file$parameter.

Ví dụ:

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

tôi có thể làm điều đó với awk:

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

này cần phải loại bỏ dấu không gian và vẻ phức tạp.

Có cách nào tốt hơn để làm điều đó không?

Trả lời

15

Dường như dấu phân cách giữa các trường là khoảng trắng. Do đó, bạn có thể sử dụng cut để chia cho họ:

file=$(echo "${MY_ARR[1]}" | cut -d' ' -f1) 
parameter=$(echo "${MY_ARR[1]}" | cut -d' ' -f2-) 
  • -f1 có nghĩa là tham số đầu tiên.
  • -f2- có nghĩa là mọi thứ từ tham số thứ hai.
+0

vâng, tôi biết về việc cắt. Tôi đã sử dụng nó với lần thử đầu tiên. Tôi từ chối sử dụng nó bởi vì tôi sợ bỏ lỡ những chiếc mũ bảo vệ thứ ba và fouth nếu là không gian ... Cần kiểm tra! – idobr

5

Bạn có thể sử dụng read:

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

Đây là giải pháp tốt hơn, vì nó không yêu cầu nhiều quy trình mới để hoàn thành nhiệm vụ (một cho lệnh thay thế, hai cho hai bên của đường ống). – chepner

2

Với mảng này:

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

Cho phép thực hiện 2 mảng MY_FILES và 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'" 

Làm thế nào để truy cập vào từng tập tin mới:

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 

Làm thế nào để truy cập mỗi tham số:

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

Từ $ kết quả trong chỉ số NUMBERS của mảng MY_FILES bạn cũng có thể sử dụng cùng một số chỉ mục để truy cập các mảng khác.Trong t theo cách của mình, bạn có thể truy cập nhiều cột dữ liệu trong cùng một vòng lặp. Cũng giống như vậy:

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

Trừ khi tôi là thiếu một cái gì đó, cách đơn giản nhất và hầu hết các di động sẽ chỉ sử dụng hai biến thể của mở rộng cho việc này.

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

Giải thích

  • "${MY_ARR[0]%%' '*}" - Điều này loại bỏ không gian đầu tiên và bất cứ điều gì sau nó, và trả về còn lại phần
  • "${MY_ARR[0]#*' '}" - Điều này loại bỏ tất cả mọi thứ lên đến không gian đầu tiên, và trả về còn lại một phần

Để có giải thích chi tiết hơn, hãy xem Parameter Expansion phần của trang bash man