Объединить несколько файлов по первому столбцу

Соответствующая проблема Snapper «Предоставьте команду 'snapper sync' для синхронизации выполняющегося удаления» была классифицирована разработчиком Snapper как «улучшение».

Это означает, что данная функция пока недоступна.

3
10.03.2021, 12:44
2 ответа

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

join -a1 -a2 -e 1 -o auto <(join -a1 -a2 -e 1 -o auto file1 file2) file3

см. в присоединение человека

-a FILENUM
also print unpairable lines from file FILENUM, where FILENUM is 1 or 2, corresponding to FILE1 or FILE2

-e EMPTY
replace missing input fields with EMPTY

-o FORMAT
obey FORMAT while constructing output line

If FORMAT is the keyword 'auto', then the first line of each file determines the number of fields output for each line.

Примечание :для соединения требуется отсортированный ввод, поэтому, если они не отсортированы (как в данных выборках ), сначала отсортируйте их, например:

join -a1 -a2 -e 1 -o auto \
    <(join -a1 -a2 -e 1 -o auto <(sort file1) <(sort file2)) \
    <(sort file3)

Чтобы применить это к нескольким файлам:

  1. объединить первые два файла и сохранить вывод в третий файл, скажемjoin.tmp:

    join -a1 -a2 -e 1 -o auto file1 file2 >join.tmp
    
  2. следующий цикл по остальным файлам и обновлениеjoin.tmpфайла для каждого запуска:

    for file in rest_files*; do
        join -a1 -a2 -e 1 -o auto join.tmp "$file" >join.tmp.1
        mv join.tmp.1 join.tmp
    done
    
  3. в конце вашjoin.tmpбудет вашим окончательным объединенным результатом.


печать с заголовком:

$ hdr() { awk 'FNR==1{ print "\0", FILENAME }1' "$1"; }
$ join -a1 -a2 -e 1 -o auto \
      <(join -a1 -a2 -e 1 -o auto <( hdr file1) <(hdr file2)) \
      <(hdr file3) |tr -d '\0'

для версии с несколькими файлами:

$ hdr() { awk 'FNR==1{ print "\0", FILENAME }1' "$1"; }
$ join -a1 -a2 -e 1 -o auto <(hdr file1) <(hdr file2) >join.tmp
$ for file in rest_files*; do
     join -a1 -a2 -e 1 -o auto join.tmp <(hdr "$file") >join.tmp.1
     mv join.tmp.1 join.tmp
  done
$ tr -d '\0' <join.tmp >final.file
4
18.03.2021, 22:26

Немного неуклюжий, но этотawk-код работает. Он использует вариант псевдо -многомерных массивов с конкатенацией SUBSEP индексов массива. Сохраняет все данные в оперативной памяти, что в этом случае ограничено.

{x[$1]=$1 ; file[FILENAME]=FILENAME ; y[$1,FILENAME]=$2}

END { for (i in file) { printf "\t%s",file[i] } ; printf "\n",""
      for (i in x) { printf "%s",x[i]
        for (j in file) { if (y[x[i],file[j]] != "")
                             { printf"\t%s",y[x[i],file[j]] }
                          else { printf"\t%s","1"}
        }
        printf "\n",""
      }
    }

Вывод ограничен только табуляцией -, для фиксированных форматов команды printf -должны быть скорректированы соответствующим образом:

    file1   file2   file3
2000    0.0202094   0.0343179   1
2001    0.0225532   1   0.03
2002    0.02553 1   1
2003    0.0261099   0.039579    1
2004    1   0.0412106   0.068689
2006    0.028843    0.041264    0.0645474
2
18.03.2021, 22:26

Теги

Похожие вопросы