У меня есть два текстовых файла, содержащих миллион записей, все записи разделены табуляцией, как мы можем объединить эти два файла на основе одного заголовка (столбец )?
файл: 1
LogEntryTime nameId PartnerId
2021-06-05T15:00:53 07 5lsddf qyutxwr
файл: 2
nameId GroupId compnayId
5lsddf l4buafm 0rd33cs
вывод примерно так:
LogEntryTime nameId PartnerId GroupId compnayId
2021-06-05T15:00:53 07 5lsddf qyutxwr l4buafm 0rd33cs
Пробовал, но не работает:
paste file1.txt file2.txt | nameId -s $'\t' -t
и
cat file1.txt file2.txt | awk -F '\t' '{print $ list the all columns name here}'
awk один, который работает, но необходимо указать все номера столбцов там.
Есть ли другое решение, которое может мне помочь.
заранее спасибо
Если ваши файлы являются правильно построенными файлами с разделением табуляций (TSV), то вы можете использовать csvjoin
из пакета csvkit
на базе Python.
Например:
$ head file1.tsv file2.tsv | cat -A
==> file1.tsv <==$
LogEntryTime^InameId^IPartnerId$
2021-06-05T15:00:53 07^I5lsddf^Iqyutxwr$
$
==> file2.tsv <==$
nameId^IGroupId^IcompnayId$
5lsddf^Il4buafm^I0rd33cs$
(cat -A
, чтобы сделать вкладки видимыми, как ^I
) затем
$ csvjoin -I -t -c nameId file1.tsv file2.tsv
LogEntryTime,nameId,PartnerId,GroupId,compnayId
2021-06-05T15:00:53 07,5lsddf,qyutxwr,l4buafm,0rd33cs
Чтобы получить вывод в формате TSV, используйте csvformat
из того же пакета:
$ csvjoin -I -t -c nameId file1.tsv file2.tsv | csvformat -T
LogEntryTime nameId PartnerId GroupId compnayId
2021-06-05T15:00:53 07 5lsddf qyutxwr l4buafm 0rd33cs
Обратите внимание, что -I
отключает вывод типов - который иногда может вести себя неожиданно, особенно с полями datetime.
Еще проще, используя Miller (доступен из репозитория universe, как пакет miller
):
$ mlr --tsv join -f file1.tsv -j nameId then reorder -f LogEntryTime file2.tsv
LogEntryTime nameId PartnerId GroupId compnayId
2021-06-05T15:00:53 07 5lsddf qyutxwr l4buafm 0rd33cs
reorder
необходим, потому что по умолчанию mlr join
выводит общее поле первым (как и системная команда join
). Обратите внимание, что для несортированного ввода в память будет загружен весь file1.tsv
.
Запустите один из файлов в массив и замените первое поле второго файла (которое является nameId
) на индекс массива, который соотносится с общим полем.
awk -F \\t+ -vOFS=\\t 'NR==FNR{a[$2]=$0;next} {$1=a[$1]}1' file{1,2}.txt
С этим конкретным набором данных:
awk '
BEGIN {FS = OFS = "\t"}
NR == FNR {f1[$2] = $0; next}
{$1 = f1[$1]; print}
' file{1,2}.txt
Упоминается только поле соединения ($ 2 в файле1, $ 1 в файле2).
Производит вывод с разделением табуляцией.
LogEntryTime nameId PartnerId GroupId compnayId
2021-06-05T15:00:53 07 5lsddf qyutxwr l4buafm 0rd33cs
Для удобного вывода вставьте конвейер в | column -t -s $ '\ t'
, чтобы получить
LogEntryTime nameId PartnerId GroupId compnayId
2021-06-05T15:00:53 07 5lsddf qyutxwr l4buafm 0rd33cs