
Как выполнить итерацию файла, в котором значения разделены запятыми?
Я попробовал следующее:
$ cat file | tr ',' '\n' > /tmp/f1
$ while read -r line;do
echo $line;
done < /tmp/f1
Как можно перебрать содержимое первой строки без создания временного файла?
Есть идеи?
решение1
Прежде всего,избегайте выполнения синтаксического анализа текста с помощью циклов оболочки. Это трудно сделать, легко ошибиться и очень трудно читать. И медленно. Очень, очень, медленно. Вместо этого используйте что-то вроде , awk
которое специально разработано для чтения по "полям". Например, с этим входным файлом:
foo, bar, baz
oof, rab, zab
Вы можете прочитать каждое поле, разделенное запятыми, используя awk -F,
для установки разделителя полей ,
:
$ awk -F, '{ print "The 1st field is",$1,"the 2nd", $2,"and the 3rd", $3}' file
The 1st field is foo the 2nd bar and the 3rd baz
The 1st field is oof the 2nd rab and the 3rd zab
Даже если вы настаиваете на выполнении этого в оболочке, вам не нужен временный файл и вам не нужен tr
. Вы можете указать while read
разделение запятыми:
$ while IFS=, read -r one two three; do
echo "The 1st field is $one, the 2nd $two and the 3rd $three";
done < file
The 1st field is foo, the 2nd bar and the 3rd baz
The 1st field is oof, the 2nd rab and the 3rd zab
решение2
Поля в CSV-файле могут занимать несколько строк, по этой и другим причинам я предпочел использоватьxsvкогда мне пришлось анализировать csv.
Один из способов анализа CSV-файла с помощью bash и xsv может быть следующим:
csvFile="myfile.csv"
lengthItems=$((($(xsv count "$csvFile") - 1 ))) # -1 because for loop start at 0
for i in $( seq 0 "$lengthItems" ); do
row="$(xsv slice -i "$i" "$csvFile")" # real magic happening here
# Do what you want with your $row here
done