이것은 쉬워 보일 수 있지만 이 문제에 갇혀 있습니다.
길이를 알 수 없는 항목이 포함된 CSV 문자열이 있습니다.
"item1,item2,item3,..."
잘라내고 해당 항목을 반복하고 싶습니다.
나는 시도했다:
while IFS=, read item;
do
echo $item
done <<< $csvString
하지만 전체 문자열을 한 번만 제공합니다.
cut
루프하는 방법을 찾을 수 없기 때문에 사용할 수 없습니다 .
답변1
read
입력이 한 줄이고 한 번에 한 줄씩 읽히기 때문에 표시된 것처럼 반복할 수 없습니다 . 이 read
작업은 첫 번째 필드와 모든 후속 필드를 사용자가 제공하는 단일 변수로 읽어옵니다.
입력 문자열 항목을 항목별로 처리하려면 각 항목을 배열 요소로 변환한 다음 해당 요소를 반복하면 됩니다.
readarray -d , -t csvArray < <( printf '%s' "$csvString" )
for item in "${csvArray[@]}"; do
printf '%s\n' "$item"
done
나는 문자열 끝에 개행 문자를 추가하는 것을 피하기 위해 위의 printf
with를 사용합니다( 개행 문자가 추가됩니다).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는 쉼표가 포함되어 있기 때문에 처음으로 방출된 레코드를 자동으로 인용합니다.
답변2
awk
다음과 같이 사용할 수도 있습니다 ( $csvString
Simple-csv 형식의 문자열을 가정).
awk -v itmStr="$csvString" '
BEGIN{
itmNr=split(itmStr, items, /,/)
for (i=1; i<=itmNr; i++)
print items[i]
}'