#awk
#awk
Вопрос:
Я пытаюсь проанализировать два csv — файла, содержащих тысячи строк. Данные должны быть сопоставлены и добавлены исключительно на основе данных в первом столбце. В настоящее время он анализирует файлы и выводит до 3 файлов:
1 - key matched 2 - file1 only 3 - file2 only
Проблема, с которой я сталкиваюсь, заключается в том, что я заметил, что как только он делает одно совпадение, он переходит к следующей строке, а не находит другие записи. для рассматриваемых данных я бы предпочел вывести несколько строк, содержащих некоторые дубликаты, чем пропустить данные nay. (Например, столбец имя варьируется в зависимости от того, кто ввел данные)
ВХОДНЫЕ ФАЙЛЫ
file1.csv topic,group,name,allow fishing,boaties,dave,yes fishing,divers,steve,no flying,red,luke,yes walking,red,tom,yes file2.csv Resource,name,email,funny fishing,frank,frank@home.com,no swiming,lee,lee@wallbanger.com,no driving,lee,lee@wallbanger.com,no
ВЫХОДНОЙ ТОК
key matched topic,group,name,allow,Resource,name,email,funny fishing,divers,steve,no,fishing,frank,frank@home.com,no file1_only topic,group,user,allow fishing,divers,steve,no flying,red,luke,yes walking,red,tom,yes file2_only Resource,user,email,funny swiming,lee,lee@wallbanger.com,no driving,lee,lee@wallbanger.com,no
Ожидаемый Результат
key matched topic,group,name,allow,Resource,name,email,funny fishing,divers,steve,no,fishing,frank,frank@home.com,no fishing,boaties,dave,yes,fishing,frank,frank@home.com,no file1_only topic,group,user,allow flying,red,luke,yes walking,red,tom,yes file2_only Resource,user,email,funny swiming,lee,lee@wallbanger.com,no driving,lee,lee@wallbanger.com,no
Поэтому для каждого ключа в столбце 1 файла 1 необходимо вывести/добавить каждый ключ, соответствующий столбцу 1 файла 2.
Это мой текущий фильтр awk. Я предполагаю, что мне нужно добавить цикл, если это возможно?
BEGIN { FS=OFS="," } FNR==1 { next } { key = $1 } NR==FNR { file1[key] = $0 next } key in file1 { print file1[key], $0 gt; "./out_combined.csv" delete file1[key] next } { print gt; "./out_file2_only.csv" } END { for (key in file1) { print file1[key] gt; "./out_file1_only.csv" } }
Комментарии:
1. являются ли ключи в столбце file21 уникальными?
2. нет, в настоящее время нет ничего уникального, поскольку эти csv-файлы были созданы на основе анализа многочисленных файлов журналов. Небольшое аудиторское упражнение.
3. какой желаемый вывод, если файл2.csv также содержит дополнительную строку
fishing,x,y@z,no
?4. сколько строк во входных данных? Тысячи? Миллионы? Триллионы? Сколько оперативной памяти на машине, выполняющей обработку? Вас волнует порядок выходных строк?
5. кстати,
file1.csv[key]
должна быть синтаксическая ошибка
Ответ №1:
$ cat tst.awk BEGIN { FS=OFS="," } FNR==1 { if ( NR==FNR ) { file1hdr = $0 } else { print file1hdr gt; "./out_file1_only.csv" print gt; "./out_file2_only.csv" print file1hdr, $0 gt; "./out_combined.csv" } next } { key = $1 } NR==FNR { file1[key, cnt[key]] = $0 next } { file2[key] if ( key in cnt ) { for ( i=1; ilt;=cnt[key]; i ) { print file1[key,i], $0 gt; "./out_combined.csv" } } else { print gt; "./out_file2_only.csv" } } END { for ( key in cnt ) { if ( !(key in file2) ) { for ( i=1; ilt;=cnt[key]; i ) { print file1[key,i] gt; "./out_file1_only.csv" } } } }
$ awk -f tst.awk file1.csv file2.csv
$ head out_* ==gt; out_combined.csv lt;== topic,group,name,allow,Resource,name,email,funny fishing,boaties,dave,yes,fishing,frank,frank@home.com,no fishing,divers,steve,no,fishing,frank,frank@home.com,no ==gt; out_file1_only.csv lt;== topic,group,name,allow flying,red,luke,yes walking,red,tom,yes ==gt; out_file2_only.csv lt;== Resource,name,email,funny swiming,lee,lee@wallbanger.com,no driving,lee,lee@wallbanger.com,no
Комментарии:
1. Спасибо, Эд, работает отлично.