Вы можете использовать команду следующим образом.
grep -Fwe "$(awk '{print $1}' file1)" file2 >output.txt
Это получение первого столбца файла1 и подача в grep
в качестве набора ШАБЛОНОВ поиска в файле2.
В предоставленных вами выборочных данных нет совпадающих данных, но это работает.
Файл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 )Распечатайте результат, отсортированный в соответствии с числовым значением строки(для упорядочения и печати имен столбцов первыми ). Также мы можем отформатировать вывод здесь, если это необходимо.
Предполагая, что ваши исходные файлы разделены табуляцией, а пустые поля по-прежнему разделены табуляцией, вы можете заполнить отсутствующие столбцы нулями с помощью 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
Альтернатива, предполагающая разделитель tab
Сначала исправьте файлы, вставив 0
между двойными tab
s или там, где заканчивается строка $
без текста (, т.е. это заголовок )или номер[^[: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
Предполагая, что ваши файлы имеют столбцы, разделенные вкладкой -, (Таким образом, вы можете определить, какие столбцы пусты в случаях, подобных третьей строке вашего 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
).