Bash配列に読み込む必要のあるfile.txtがあります。次に、スペース、二重引用符、およびすべてのエントリの最初のカンマを除くすべてを削除する必要があります。これが私がどこまで得たかです:
$ 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
beforeを使用して削除する必要があるものを配列にロードします(また、小文字の変数名にも注意してください。一般に、シェルスクリプトでは大文字の変数を使用しないことをお勧めします)。
#!/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
は、g
コマンドへのフラグとして2
とs
の組み合わせをサポートしていません)。
ELEMENT='50,n,e,e,d,2'
IFS=, read -r first rest <<<"$ELEMENT"
printf "%s,%s\n" "$first" "${rest//,/}"
50,need2
ALLCAPS変数名を使用する習慣から抜け出します。最終的には、PATHなどの重要な「システム」変数と衝突し、コードを破壊します。
[これは本質的に、より完全に開発されたバージョン glenn jackmann's answer ]です。
最初のコンマをセパレーターとして使用して、除去されたキーと値から連想配列を作成します。
declare -A arr
while IFS=, read -r k v; do arr["${k//[ \"]}"]="${v//[ ,\"]}"; done < file.txt
for k in "${!arr[@]}"; do
printf '|ELEMENT|%s,%s|\n' "$k" "${arr[$k]}"
done
|ELEMENT|20,is|
|ELEMENT|10,this|
|ELEMENT|50,need2|
|ELEMENT|40,I|
|ELEMENT|60,see|
|ELEMENT|30,all|
配列をループして中間変数を使用できます。
for((i=0; i < "${#ARRAY[@]}"; i++))
do
rest="${ARRAY[i]#*,}"
ARRAY[i]="${ARRAY[i]%%,*}","${rest//,/}"
done
これは、最初のカンマの後の部分をrest
に割り当てます。次に、3つの部分を連結して元の変数に戻します。
rest
のすべてのカンマの置換