Извлечение данных из файла и размещение в разных файлах на основе значения одного столбца

14

Мы сгенерируем CSV-файл со значениями ниже

yp1234,577,1,3
yp5678,577,3,5
yp9012,132,8,9

Мне нужно извлечь данные и создать файлы на основе второго столбца. Если это 577, то вся строка должна быть извлечена и помещена в отдельный файл. Я имею в виду, что мне нужен файл со строками со вторым столбцом только 577 и другой файл со вторым столбцом 132

Я пытался использовать IF, но не работал

user3116123
источник
5
На самом деле размещение кода, который не работает, всегда хорошая идея.
Златовласка

Ответы:

27

Используйте awk:

awk -F, '{ print > $2 ".csv" }' file.csv

Это создаст два файла 577.csvи 132.csvв вашем текущем каталоге.

Команда выше предполагает, что вы можете иметь только 132или 577как второе поле. Это создаст одно имя файла для каждого из значений, найденных во втором поле целого file.csv.

Если есть другие значения помимо двух, которые вас интересуют, и вы хотите игнорировать эти строки, сделайте это вместо:

awk -F, '$2 == "577" || $2 == "132" { print > $2 ".csv" }' file.csv
Тердон
источник
1
Есть ошибочные awkреализации, которые нельзя использовать print > $2 ".cvs". На тех, вы должны сначала вычислить имя файла, а затем выполните print: fname = $2 ".cvs"; print > fname.
Кусалананда
3

Мне нравится awkрешение Тердона , но для полноты, вот предложение, использующее толькоbash

while IFS=, read -r a1 a2 a3 a4; do 
    echo "$a1,$a2,$a3,$a4" >> "$a2".csv
done < file.csv

Он будет производить файлы 577.csvи 132.csvв текущем каталоге.

grebneke
источник
3

Извлечь все 577 в стандартный вывод

grep -e '^.*,577,.*,.*$' youfile.csv >result_extract_557.csv

- отредактируйте 1 Исправлено на основе комментария @ terdon ниже, чтобы избежать ложных совпадений, когда по крайней мере 3 запятых на линии с 577.

grep -e '^[:alnum:]*,577,[:digit:]*,[:digit:]*$' youfile.csv >result_extract_557.csv

Но я думаю, что его / ее awkрешение является более полным.

X Тянь
источник
Это будет совпадать, даже если 577 находится на другом поле, а не на втором, или если оно является частью поля. Например foo577barили yp9012,132,8,577.
Terdon
Я думал, что мои запятые сделают это поле зависимым?
X Tian
Извините, я привел плохие примеры, но .*они также могут совпадать с запятыми, чтобы вы не знали, какое поле вы подходите. Может быть вторым, также может быть 45-м. Моя вторая жалоба была неправильной, вы правы в том, что запятые защищают от совпадения foo577bar.
Terdon
что делать если | символ используется вместо.
user3116123
ошибка ниже: grep: недопустимая опция - e Использование: файл шаблона grep -hblcnsviw. , ,
user3116123
1

Использование csvkit:

$ csvgrep -c 2 -m 577 data.csv >output.csv

Команда -c 2make cvsgrepрассматривает второй столбец, и -m 577мы просим его сопоставить строку 577в этом столбце.

Следующее будет написано output.csv:

yp1234,577,1,3
yp5678,577,3,5

Чтобы сопоставить количество строк и записать вывод в файл для каждой строки:

for pattern in 577 132; do
  csvgrep -c 2 -m "$pattern" data.csv >"output-$pattern.csv"
done

Это создаст два файла output-132.csvи output-577.csv.

Кусалананда
источник