AWK — сравните столбец $1 , добавьте строки, которые совпадают (включая дубликаты)

#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. Спасибо, Эд, работает отлично.