Bash

在 Bash 數組上使用參數替換

  • March 26, 2019

我有 file.txt 需要讀入 Bash 數組。然後我需要刪除每個條目中的空格、雙引號和除第一個逗號之外的所有內容。這是我已經走了多遠:

$ cat file.txt
10,this
2 0 , i s
30,"all"
40,I
50,n,e,e,d,2
60",s e,e"

$ cat script.sh
#!/bin/bash
readarray -t ARRAY<$1
ARRAY=( "${ARRAY[@]// /}" )
ARRAY=( "${ARRAY[@]//\"/}" )
for ELEMENT in "${ARRAY[@]}";do
   echo "|ELEMENT|$ELEMENT|"
done

$ ./script.sh file.txt
|ELEMENT|10,this|
|ELEMENT|20,is|
|ELEMENT|30,all|
|ELEMENT|40,I|
|ELEMENT|50,n,e,e,d,2|
|ELEMENT|60,se,e|

除了逗號情況外,效果很好。我知道有多種方法可以給這隻貓換皮,但由於腳本較大,這是其中的一部分,我真的很想使用參數替換來到達這裡:

|ELEMENT|10,this|
|ELEMENT|20,is|
|ELEMENT|30,all|
|ELEMENT|40,I|
|ELEMENT|50,need2|
|ELEMENT|60,see|

這可以通過參數替換嗎?

sed 在載入到數組之前,我會刪除你需要刪除的內容(還要注意小寫的變數名,通常最好避免在 shell 腳本中使用大寫的變數):

#!/bin/bash
readarray -t array< <(sed 's/"//g; s/  *//g; s/,/"/; s/,//g; s/"/,/' "$1")
for element in "${array[@]}";do
   echo "|ELEMENT|$element|"
done

這會在您的範例文件中生成以下輸出:

$ foo.sh file 
|ELEMENT|10,this|
|ELEMENT|20,is|
|ELEMENT|30,all|
|ELEMENT|40,I|
|ELEMENT|50,need2|
|ELEMENT|60,see|

如果您確實必須使用參數替換,請嘗試以下操作:

#!/bin/bash
readarray -t array< "$1"
array=( "${array[@]// /}" )
array=( "${array[@]//\"/}" )
array=( "${array[@]/,/\"}" )
array=( "${array[@]//,/}" )
array=( "${array[@]/\"/,}" )

for element in "${array[@]}"; do
   echo "|ELEMENT|$element|"
done

據我所見,無需將其讀入bash數組即可創建該輸出:

$ sed 's/[ "]//g; s/,/ /; s/,//g; s/ /,/; s/.*/|ELEMENT|&|/' <file
|ELEMENT|10,this|
|ELEMENT|20,is|
|ELEMENT|30,all|
|ELEMENT|40,I|
|ELEMENT|50,need2|
|ELEMENT|60,see|

sed表達式刪除空格和雙引號,將第一個逗號替換為空格(此時字元串中沒有其他空格),刪除所有其他逗號,恢復第一個逗號,以及前置和附加額外數據。

或者,使用 GNU sed

sed 's/[ "]//g; s/,//2g; s/.*/|ELEMENT|&|/' <file

(標準sed不支持將2和組合為命令g的標誌s)。

引用自:https://unix.stackexchange.com/questions/508777