Как разобрать CSV файл в Bash?
Я работаю над длинным Bash script. Я хочу читать ячейки из файла CSV в переменные Bash. Я могу разобрать строки и первый столбец, но не любой другой столбец. Вот мой код:
cat myfile.csv|while read line
do
read -d, col1 col2 < <(echo $line)
echo "I got:$col1|$col2"
done
Он печатает только первый столбец. В качестве дополнительного теста я попробовал следующее:
read -d, x y < <(echo a,b,)
И $y пуст. Поэтому я попробовал:
read x y < <(echo a b)
И $y - b
. Почему?
Ответы
Ответ 1
Вам нужно использовать IFS
вместо -d
:
while IFS=, read -r col1 col2
do
echo "I got:$col1|$col2"
done < myfile.csv
Обратите внимание, что для синтаксического анализа CSV общего назначения вы должны использовать специализированный инструмент, который может обрабатывать поля с кодами с внутренними запятыми, среди других проблем, которые Bash не может обрабатывать сам по себе. Примерами таких инструментов являются cvstool
и csvkit
.
Ответ 2
На странице man
:
-d delim Первый символ delim используется для завершения ввода строки, вместо новой строки.
Вы используете -d,
, который завершит ввод строки в запятой. Он не будет читать остальную часть строки. Поэтому $y пуст.
Ответ 3
Мы можем проанализировать CSV файлы со строками в кавычках и разделенными с помощью say | со следующим кодом
while read -r line
do
field1=$(echo $line | awk -F'|' '{printf "%s", $1}' | tr -d '"')
field2=$(echo $line | awk -F'|' '{printf "%s", $2}' | tr -d '"')
echo $field1 $field2
done < $csvFile
awk разбирает строковые поля на переменные и tr удаляет кавычки.
Немного медленнее, поскольку awk выполняется для каждого поля.
Ответ 4
Если вы хотите прочитать файл CSV с несколькими строками, то это решение.
while IFS=, read -ra line
do
test $i -eq 1 && ((i=i+1)) && continue
for col_val in ${line[@]}
do
echo -n "$col_val|"
done
echo
done < "$csvFile"