объединить несколько файлов txt

Вы можете использовать команду следующим образом.

grep -Fwe "$(awk '{print $1}' file1)" file2 >output.txt

Это получение первого столбца файла1 и подача в grepв качестве набора ШАБЛОНОВ поиска в файле2.

В предоставленных вами выборочных данных нет совпадающих данных, но это работает.

0
04.12.2019, 22:45
4 ответа

Файл3 не совсем корректен с моей точки зрения, так как строка

5811151 12

может иметь число "12" во втором или третьем столбце, в зависимости от того, как мы читаем файл (разделитель столбцов не определен и не везде одинаков ).

В любом случае.

a=$(cat file1|awk '{if($2==""){$2="0"};if($3==""){$3="0"}; print $1,$2,$3}'|sort);
for f in file2 file3; do
    b=$(cat $f|awk '{if($2==""){$2="0"};if($3==""){$3="0"}; print $1,$2,$3}'|sort);
    a=$(join -j 1 <(echo "${a}") <(echo "${b}"));
done;
echo "${a}"|sort -n

вывод

sample input filtered chi tri bra doe
5809378 1 2 7 8 11 0
5811151 3 4 0 0 12 0
5811237 5 6 9 10 13 14

Итак, мы

1 )Преобразование каждого взятого файла

cat file|awk '{if($2==""){$2="0"};if($3==""){$3="0"}; print $1,$2,$3}'|sort

заменить отсутствующие числа на «0» и отсортировать строки.

2 )В цикле мы берем следующий файл и объединяем его с предыдущим результатом

join -j 1 file_current file_next

поэтому строка «для f в файле2 файл3; делать» может быть изменена, чтобы включать больше файлов, например, «для f в файле2 файл3 файл4 файл5 файл6; делать».

3 )Распечатайте результат, отсортированный в соответствии с числовым значением строки(для упорядочения и печати имен столбцов первыми ). Также мы можем отформатировать вывод здесь, если это необходимо.

0
28.01.2020, 03:03

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

awk -F'     ' '!$2{$2=0}!$3{$3=0}{print}' file1 > file1-n
awk -F'     ' '!$2{$2=0}!$3{$3=0}{print}' file2 > file3-n
awk -F'     ' '!$2{$2=0}!$3{$3=0}{print}' file3 > file3-n

Это awk -F '<TAB>', чтобы было ясно. Затем вы можете использовать вставку, чтобы объединить их, с другим awk для фильтрации ненужных столбцов :

.
bash-$ paste file1-n file2-n file3-n | awk {'print $1, $2, $3, $5, $6, $8, $9'}
sample input filtered chi tri bra doe
5809378 1 2 7 8 11 0
5811151 3 4 0 0 0 12
5811237 5 6 9 10 13 14

Или разделяйте столбцы, если важна удобочитаемость для человека:

bash-$ paste file1-n file2-n file3-n | awk {'printf "%-7s %-5s %-8s %-3s %-3s %-3s %-3s\n", $1, $2, $3, $5, $6, $8, $9'}
sample  input filtered chi tri bra doe
5809378 1     2        7   8   11  0
5811151 3     4        0   0   0   12
5811237 5     6        9   10  13  14
0
28.01.2020, 03:03

Альтернатива, предполагающая разделитель tab

Сначала исправьте файлы, вставив 0между двойными tabs или там, где заканчивается строка $без текста (, т.е. это заголовок )или номер[^[:alnum:]]

TAB=$'\t'; sed -Ei "s/([^[:alnum:]]|${TAB})($|${TAB})/\10\2/g" file*

Тогда просто joinих

join --header file2 file3 | join --header file1 - | column -t

Выход

sample   input  filtered  chi  tri  bra  doe
5809378  1      2         7    8    11   0
5811151  3      4         0    0    0    12
5811237  5      6         9    10   13   14
0
28.01.2020, 03:03

Предполагая, что ваши файлы имеют столбцы, разделенные вкладкой -, (Таким образом, вы можете определить, какие столбцы пусты в случаях, подобных третьей строке вашего file3), и отсортированы по первому столбцу, как ваши образцы, скрипт bash вот так:

#!/bin/bash

function fixup() { # Add 0's to blank columns
    awk -v cols="$2" 'BEGIN { FS = OFS = "\t" }
                      { for (i = 1; i <= cols; i++)
                         if ($i == "") $i = 0
                      } 1' "$1"
}

join --header -t$'\t' -j1 \
     <(join --header -t$'\t' -j1 <(fixup "$1" 3) \
                                 <(fixup "$2" 3)) \
     <(fixup "$3" 3)

сделаю это:

$./combine file1 file2 file3
sample  input   filtered        chi     tri     bra     doe
5809378 1       2       7       8       11      0
5811151 3       4       0       0       0       12
5811237 5       6       9       10      13      14

(Требуется версия GNU coreutilsjoin).

0
28.01.2020, 03:03

Теги

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