bashで不明な値の数で文字列CSV変数を切り取り、その値を繰り返す方法は?

bashで不明な値の数で文字列CSV変数を切り取り、その値を繰り返す方法は?

これは簡単に見えるかもしれませんが、この問題に閉じ込められています。

長さが不明な項目を含むCSV文字列があります。

"item1,item2,item3,..."

切り取り、その項目を繰り返したいです。

私は試した:

while IFS=, read item;
do
   echo $item
done <<< $csvString

しかし、文字列全体を一度だけ提供します。

cutループする方法が見つからないため使用できません。

ベストアンサー1

read入力が1行で一度に1行ずつ読み取られるため、示されているように繰り返すことはできません。このread操作は、最初のフィールドとすべての後続のフィールドをユーザーが提供する単一の変数として読み取られます。

入力文字列項目を項目ごとに処理するには、各項目を配列要素に変換してからその要素を繰り返すだけです。

readarray -d , -t csvArray < <( printf '%s' "$csvString" )

for item in "${csvArray[@]}"; do
    printf '%s\n' "$item"
done

私は文字列の末尾に改行文字を追加することを避けるために上記のprintfwithを使用します(改行文字が追加されます)。readarray<<<"$csvString"

ただし、入力文字列がカンマ区切りの単純な部分文字列のリストではなくCSV文字列の場合、readarray一部のフィールドに区切り文字が含まれている可能性があるため、文字列を正しく分割できません。 Miller()などのCSV認識ツールを使用してmlr文字列を解析し、必要な操作を実行できます。

$ csvString='"1, 2, 3",Hello world,A,B,C'
$ mlr --csv -N put -q 'for (k,v in $*) { emit v }' <<<"$csvString"
"1, 2, 3"
Hello world
A
B
C

上記mlrのコマンドは、ヘッダーなしの単一のCSV入力レコードを繰り返し、各フィールドの値を新しいレコードに出力します。 Millerにはカンマが含まれているため、最初にリリースされたレコードを自動的に引用します。

おすすめ記事