2014-11-17 3 views
2

У меня есть файл CSV размером около 800 мб, который мне нужно разделить с помощью AWK. Файл имеет столбец с идентификаторами в них, который я хочу использовать для разделения файла. Я знаком/знаю, как это сделать с Perl, но не с AWK, так как я только использовал его несколько раз. (В perl я бы использовал модуль Text :: CSV, но у меня нет возможности в этом случае)AWK Сплит большой файл CSV с заголовками и выходными файлами на основе значения столбца

Я нашел этот ответ: https://stackoverflow.com/a/16795137 который в основном я хочу, но с небольшим изменением. Он должен содержать оператор if, поэтому он будет печатать только в том случае, если столбец, который я хочу разбить на нем, является цифрой. Это необходимо, потому что столбец файлов может иногда меняться, и я хочу отправить нецифровые строки в отдельный файл (junk.csv).

Я использую версию Windows cmd для тестирования прямо сейчас, но я в конечном итоге запустил ее на linux. (Ниже исходный код)

awk -F, "NR==1{hdr=$0;next}!($3 in files){files[$3]=1;print hdr\"\n\">$3\".csv\"}{print>$3\".csv\"}" test.csv 

И мое намерение состоит в следующем:

awk -F";" "{if ($3 ~ /^[0-9]+$/){"NR==1{hdr=$0;next}!($3 in files){files[$3]=1;print hdr>$3\".csv\"}{print>$3\".csv\"}"" test.csv 

Я не могу понять, как это сделать в AWK (только пока). Двойные кавычки также отбрасывают меня (из-за версии Windows). Где я иду не так?

Это моя ошибка выхода:

awk: {if($3 ~ /^[0-9]+$/) NR==1{hdr=$0;next}!($3 in files){files[$3]=1;print hdr>$3".csv"}{print>$3.csv};else print>junk.csv} 
awk:       ^syntax error 
awk: {if($3 ~ /^[0-9]+$/) NR==1{hdr=$0;next}!($3 in files){files[$3]=1;print hdr>$3".csv"}{print>$3.csv};else print>junk.csv} 
awk:             ^syntax error 
awk: {if($3 ~ /^[0-9]+$/) NR==1{hdr=$0;next}!($3 in files){files[$3]=1;print hdr>$3".csv"}{print>$3.csv};else print>junk.csv} 
awk:                         ^syntax error 
awk: {if($3 ~ /^[0-9]+$/) NR==1{hdr=$0;next}!($3 in files){files[$3]=1;print hdr>$3".csv"}{print>$3.csv};else print>junk.csv} 
awk:                             ^syntax error 
errcount: 4 

Это мой (образец) данные:

10002394;22.98;48;http://testdata.com/bla/29012827.jpg;5.95;93962094820 
10003062;19.99;26;http://testdata.com/bla/29002816.jpg;5.95;17012725049 
10003122;13.0;53;http://testdata.com/bla/29019899.jpg;5.95;24404000059 
10004766;12.99;48;http://testdata.com/bla/29007085.jpg;5.95;95074666117 
10007645;20.99;65;http://testdata.com/bla/28798580.jpg;5.95;10201848233 
10009363;119.0;53;http://testdata.com/bla/29004907.jpg;5.95;9823036360 
10009631;19.95;48;http://testdata.com/bla/29013097.jpg;5.95;20689058198 
10010119;9.99;48;http://testdata.com/bla/29016592.jpg;5.95;80076014280 
10012615;20.99;53;http://testdata.com/bla/28772382.jpg;5.95;3948187983 
10015250;14.99;48;http://testdata.com/bla/29015812.jpg;5.95;93962045440 
10019190;69.99;53;http://testdata.com/bla/29010968.jpg;5.95;948187983 
10025155;27.99;65;http://testdata.com/bla/29011075.jpg;5.95;14201021349 
10025825;12.99;65;http://testdata.com/bla/29017837.jpg;5.95;93962025367 
10029650;27.99;48;http://testdata.com/bla/29003007.jpg;5.95;3692164452 
10034957;34.99;53;http://testdata.com/bla/29000529.jpg;5.95;42872898825 
10041967;24.99;65;http://testdata.com/bla/28781700.jpg;5.95;91229911080 
10045277;59.99;65;http://testdata.com/bla/29010583.jpg;5.95;67365082290 
10045795;10.99;48;http://testdata.com/bla/29002819.jpg;5.95;19422308188 
10048375;26.99;26;http://testdata.com/bla/29002270.jpg;5.95;95082912275 
10052550;19.99;48;http://testdata.com/bla/29016347.jpg;5.95;7368425436 

И я хочу сделать это:

File --> 26.csv 
10003062;19.99;26;http://testdata.com/bla/29002816.jpg;5.95;17012725049 
10048375;26.99;26;http://testdata.com/bla/29002270.jpg;5.95;95082912275 

File --> 48.csv 
10002394;22.98;48;http://testdata.com/bla/29012827.jpg;5.95;93962094820 
10004766;12.99;48;http://testdata.com/bla/29007085.jpg;5.95;95074666117 
10009631;19.95;48;http://testdata.com/bla/29013097.jpg;5.95;20689058198 
10010119;9.99;48;http://testdata.com/bla/29016592.jpg;5.95;80076014280 
10015250;14.99;48;http://testdata.com/bla/29015812.jpg;5.95;93962045440 
10029650;27.99;48;http://testdata.com/bla/29003007.jpg;5.95;3692164452 
10045795;10.99;48;http://testdata.com/bla/29002819.jpg;5.95;19422308188 
10052550;19.99;48;http://testdata.com/bla/29016347.jpg;5.95;7368425436 

File --> 53.csv 
10003122;13.0;53;http://testdata.com/bla/29019899.jpg;5.95;24404000059 
10009363;119.0;53;http://testdata.com/bla/29004907.jpg;5.95;9823036360 
10012615;20.99;53;http://testdata.com/bla/28772382.jpg;5.95;3948187983 
10019190;69.99;53;http://testdata.com/bla/29010968.jpg;5.95;948187983 
10034957;34.99;53;http://testdata.com/bla/29000529.jpg;5.95;42872898825 

File --> 65.csv 
10007645;20.99;65;http://testdata.com/bla/28798580.jpg;5.95;10201848233 
10025155;27.99;65;http://testdata.com/bla/29011075.jpg;5.95;14201021349 
10025825;12.99;65;http://testdata.com/bla/29017837.jpg;5.95;93962025367 
10041967;24.99;65;http://testdata.com/bla/28781700.jpg;5.95;91229911080 
10045277;59.99;65;http://testdata.com/bla/29010583.jpg;5.95;67365082290 

ответ

3

Вы можете упростить awk как

awk -F\; '{print > $3".csv"}' input 

будет производить следующие csv файлов с содержанием

26.csv 
10003062;19.99;26;http://testdata.com/bla/29002816.jpg;5.95;17012725049 
10048375;26.99;26;http://testdata.com/bla/29002270.jpg;5.95;95082912275 
48.csv 
10002394;22.98;48;http://testdata.com/bla/29012827.jpg;5.95;93962094820 
10004766;12.99;48;http://testdata.com/bla/29007085.jpg;5.95;95074666117 
10009631;19.95;48;http://testdata.com/bla/29013097.jpg;5.95;20689058198 
10010119;9.99;48;http://testdata.com/bla/29016592.jpg;5.95;80076014280 
10015250;14.99;48;http://testdata.com/bla/29015812.jpg;5.95;93962045440 
10029650;27.99;48;http://testdata.com/bla/29003007.jpg;5.95;3692164452 
10045795;10.99;48;http://testdata.com/bla/29002819.jpg;5.95;19422308188 
10052550;19.99;48;http://testdata.com/bla/29016347.jpg;5.95;7368425436 
53.csv 
10003122;13.0;53;http://testdata.com/bla/29019899.jpg;5.95;24404000059 
10009363;119.0;53;http://testdata.com/bla/29004907.jpg;5.95;9823036360 
10012615;20.99;53;http://testdata.com/bla/28772382.jpg;5.95;3948187983 
10019190;69.99;53;http://testdata.com/bla/29010968.jpg;5.95;948187983 
10034957;34.99;53;http://testdata.com/bla/29000529.jpg;5.95;42872898825 
65.csv 
10007645;20.99;65;http://testdata.com/bla/28798580.jpg;5.95;10201848233 
10025155;27.99;65;http://testdata.com/bla/29011075.jpg;5.95;14201021349 
10025825;12.99;65;http://testdata.com/bla/29017837.jpg;5.95;93962025367 
10041967;24.99;65;http://testdata.com/bla/28781700.jpg;5.95;91229911080 
10045277;59.99;65;http://testdata.com/bla/29010583.jpg;5.95;67365082290 

ПРИМЕЧАНИЕ

Если вы хотите послать строки, которые имеют не являющиеся цифры в колонке 3, junk.csv небольшого изменения в приведенном выше AWK может быть полезным

awk -F\; '$3 ~ /^[0-9]+$/{print > $3".csv"; next} {print > "junk.csv"}' input 
  • $3 ~ /^[0-9]+$/ выполняет регулярное выражение в столбце 3, и если оно соответствует, отправляется в соответствующий файл csv. иначе строка записывается в junk.csv

ИЛИ

гораздо проще вариант, как

awk -F\; '{file=$3~/^[0-9]+$/?$3:"junk";print >file".csv"}' 

Благодаря Jidder по предложению.

+0

Примечание 'print' достаточно,' print $ 0' не требуется. Кроме того, чтобы проверить, что поле является числовым/нет, вы можете использовать '/^[0-9] + $ /'.Это будет соответствовать всем, имеющим только цифры (и, по крайней мере, один). – fedorqui

+0

@fedorqui Я внес изменения с помощью 'print'. Спасибо вам за это. Но я не уверен, что ваш второй момент извините. Я написал это как '$ 3 ~/^ [0-9] + $ /', который соответствует только цифрам – nu11p01n73R

+0

Да, это именно то, что я имел в виду. Когда я прокомментировал это, у вас было что-то немного другое, например '$ 3 ~/[0-9] + /', которое соответствовало бы строкам типа '23a'. – fedorqui