У меня есть несколько файлов CSV со многими записями. Общее количество строк должно быть 134. У меня много файлов, и у каждой строки есть свое количество столбцов (от 15 до 200). Мне нужно отсортировать их по количеству столбцов.
Мне удалось подсчитать столбцы файла, используя:
$ awk -F"," '{print NF}' file # 1.csv
… который дает что-то вроде:
134 134 134 5 25 133 ...
Теперь я хотел бы добавить эти числа в каждую строку, чтобы впоследствии я мог сортировать свои строки в соответствии с ними. Как я могу добавить эту информацию в начале каждого и сортировать?
Я также хотел бы разделить файлы со значением = 134 в 1 файл другим по их счету.
пример небольшого INPUT файла (это 3 строки):
2,"ABCD",50,"SDf3oa701-ab73-a0pcs90","7012218969217-1413752517-32448","SDf3oa701-ab73-a0pcs90","SIP",,"<99999@sipgw5003.com>;tag=70122","<8888888@XYZW>",17,0,"00:01:57.827 GMT Oct 20 2014","00:00:00.000 UTC Jan 01 1970","00:01:57.870 GMT Oct 20 2014",3,"sp3",1904,"sp3",1904,"realm_IN","realmTERM_OUT",,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,"Sw-buildabcd","GMT-03:00",0,"8888888@XYZW",,,,,,"XYZW:50","ASDF:50","ASDF:50","ASDF:50",,1,2,1,404,"8888888@ASDF",,,4493101 2,"ABCD",50,,,,4493105 2,"ABCD",50,,"88888@BDSE",,,4493106
-2,"ABCD",50,"SDf3oa701-ab73-a0pcs90","7012218969217-1413752517-32448","SDf3oa701-ab73-a0pcs90","SIP",,"<99999@sipgw5003.com>;tag=70122","<8888888@XYZW>",17,0,"00:01:57.827 GMT Oct 20 2014","00:00:00.000 UTC Jan 01 1970","00:01:57.870 GMT Oct 20 2014",3,"sp3",1904,"sp3",1904,"realm_IN","realmTERM_OUT",,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,,"::",0,"::",0,,"::",0,"::",0,0,0,0,0,0,0,0,0,0,0,,,"Sw-buildabcd","GMT-03:00",0,"8888888@XYZW",,,,,,"XYZW:50","ASDF:50","ASDF:50","ASDF:50",,1,2,1,404,"8888888@ASDF",,,4493101 2,"ABCD",50,,,,4493105 2,"ABCD",50,,"88888@BDSE",,,4493106
Думайте, это то, что вы хотите
Добавьте -F,
для запятой.
Например, awk -F, '$(NF+1)=NF' file
awk '$(NF+1)=NF' file
вход
1 1 2 3 1 2 1 2 3 4 5 6 ab
Вывод
1 1 1 2 3 3 1 2 2 1 2 3 4 5 6 6 ab 2
awk '{a[NF]=a[NF]?a[NF]"\n"$0:$0;x=x<NF?NF:x}END{for(i=1;i<=x;i++)if(i in a)print a[i]}'
вход
1 1 2 3 1 2 1 2 3 4 5 6 ab
Вывод
1 1 2 ab 1 2 3 1 2 3 4 5 6
Например, используя длину поля 4, измените значение 134 или все, что вы хотите для своего
awk '{print > (NF>=4?"LargeFile.txt":"SmallFile.txt")}' file
вход
1 1 2 3 1 2 1 2 3 4 5 6 ab
Вывод
LargeFile.txt
1 2 3 4 5 6
SmallFile.txt
1 1 2 3 1 2 ab
Как и ответ @ terdon, но с sed
:
{ seq -s, 10; seq -s, 5; seq -s, 15; } | tee - -
Это мой infile – это выглядит так:
1,2,3,4,5,6,7,8,9,10 1,2,3,4,5,6,7,8,9,10 1,2,3,4,5,6,7,8,9,10 1,2,3,4,5 1,2,3,4,5 1,2,3,4,5 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
Тогда я могу:
sed 'h;s/[^,]*//g;G;s/\n/ /' | sort -t\ -nk1,1
… который получает …
,,,, 1,2,3,4,5 ,,,, 1,2,3,4,5 ,,,, 1,2,3,4,5 ,,,,,,,,, 1,2,3,4,5,6,7,8,9,10 ,,,,,,,,, 1,2,3,4,5,6,7,8,9,10 ,,,,,,,,, 1,2,3,4,5,6,7,8,9,10 ,,,,,,,,,,,,,, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ,,,,,,,,,,,,,, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ,,,,,,,,,,,,,, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
Цифров нет, но, конечно, число вполне достаточно. Чтобы удалить ведущие запятые, я могу просто сделать:
PIPELINE | sed 's/,* //'
… который получает …
1,2,3,4,5 1,2,3,4,5 1,2,3,4,5 1,2,3,4,5,6,7,8,9,10 1,2,3,4,5,6,7,8,9,10 1,2,3,4,5,6,7,8,9,10 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
Возможно, это не самый благоприятный ответ, но основная причина, по которой я решил написать это, заключалась в том, что вы упоминаете, что хотите записать строки с 134 разделенными запятыми элементами в другой файл. Это, как бывает, простое дело с sed
. Например, скажем, я хотел написать строки с 10 полями из приведенной выше последовательности в file2
:
PIPELINE | sed '/^\([^,]*,[^,]*\)\{9\}$/w file2' cat file2
1,2,3,4,5,6,7,8,9,10 1,2,3,4,5,6,7,8,9,10 1,2,3,4,5,6,7,8,9,10
Я использую \{9\}
выше, потому что он указывает 9 экземпляров шаблона, что делает 9 разделителей для 10 полей с разделителями. Диапазоны просто обрабатываются:
PIPELINE | sed '/^\([^,]*,[^,]*\)\{4,9\}$/w file2' cat file2
1,2,3,4,5 1,2,3,4,5 1,2,3,4,5 1,2,3,4,5,6,7,8,9,10 1,2,3,4,5,6,7,8,9,10 1,2,3,4,5,6,7,8,9,10
Это добавит количество полей (разделенных запятыми) в начало каждой строки, распечатает строку и затем отсортирует все:
awk -F"," '{print NF,$0}' *csv | sort -nk1,1
-n
– числовая сортировка, а -k1,1
гарантирует, что она будет сортироваться только в первом поле. Чтобы удалить количество полей после сортировки, используйте:
awk -F"," 'print NF,$0' *csv | sort -nk1,1 | cut -d ' ' -f 2-
ПРИМЕЧАНИЕ . Это будет очень легко ломаться в зависимости от ваших фактических данных. Можете ли вы иметь запятые в полях? У вас есть поля, охватывающие несколько строк? Это очень наивный подход и не может справиться ни с одним из них.