сопоставление столбцов в двух файлах и изменение результирующего файла - PullRequest
1 голос
/ 24 июня 2019

У меня есть два файла, один с 3 столбцами и один с 4 столбцами.Они выглядят так:

файл 1:

air 0.1 0.2
soil 0.9 0.7
water 0.4 0.6

файл 2:

temp1 0.1 0.2 air
temp2 0.5 0.6 .
temp3 0.6 0.3 water

Если значения столбца 4 в файле 2 соответствуют значению столбца 1 в файлевыходные данные должны выглядеть следующим образом:

temp1 0.1 0.2 air 0.1

, то есть все значения файла 2 и первых двух столбцов файла 1. В случае несоответствия должна быть напечатана вся строка файла 2, как есть:

Таким образом, конечный результат будет

temp1 0.1 0.2 air 0.1
temp2 0.5 0.6 .
temp3 0.6 0.3 water 0.4

, если это будет нормальное совпадение значений из двух файлов, можно использовать что-то вроде этого:

for i in `cat file 1`; do awk '{if($4=="'$i'") print $0_}'<file2 >>output; done

однако кодтребуется больше, чем это.

Кто-нибудь может мне помочь исправить это.

Спасибо

Ответы [ 3 ]

4 голосов
/ 24 июня 2019

Это действительно похоже на классическое использование join . Утилита join используется для объединения файлов в определенных полях (файлы должны быть отсортированы). Этот ответ не использует awk, не знаю, если это проблема.

cat <<EOF >file1
air 0.1 0.2
soil 0.9 0.7
water 0.4 0.6
EOF
cat <<EOF >file2
temp1 0.1 0.2 air
temp2 0.5 0.6 .
temp3 0.6 0.3 water
EOF

# separator is space
# join on the first field from first file
# join on the firth field from the second file
# in case the lines are not matched, print the line from second file
# output - first output 4 fields from file 2 and second field from file 2
#          it is the same as 3 fields from file 2 and 2 fields from file 1
join -t' ' -11 -24 -a2 -o 2.1,2.2,2.3,2.4,1.2 file1 file2

выведет:

temp1 0.1 0.2 air 0.1
temp2 0.5 0.6 .
temp3 0.6 0.3 water 0.4

проверено на repl .

Если ваши входные файлы не отсортированы, вам необходимо предварительно отсортировать их по определенным полям:

 join -t' ' -11 -24 -a2 -o 2.1,2.2,2.3,2.4,1.2 <(<file1 sort -t' ' -k1) <(<file2 sort -t' ' -k4)

Если ваши входные файлы не отсортированы, и вам необходимо сохранить порядок сортировки из файла 2, пронумеровать строки в файле 2, объединить их, отсортировать выходные данные, используя номера строк из файла 2, и удалить эти номера строк:

 join -t' ' -11 -25 -a2 -o 2.1,2.2,2.3,2.4,2.5,1.2 <(<file1 sort -t' ' -k1) <(<file2 nl -w1 -s' ' | sort -t' ' -k5) | sort -t' ' -k1 | cut -d' ' -f2-
3 голосов
/ 24 июня 2019
$ awk 'NR==FNR{a[$1]=$2; next} {print $0 ($4 in a ? OFS a[$4] : "")}' file1 file2
temp1 0.1 0.2 air 0.1
temp2 0.5 0.6 .
temp3 0.6 0.3 water 0.4
2 голосов
/ 24 июня 2019

Perl в помощь!

#!/usr/bin/perl
use warnings;
use strict;

my %F1;
open my $f1, '<', shift or die $!;
while (<$f1>) {
    my ($id, $value) = split;
    warn "Duplicate entry for $id.\n" if exists $F1{$id};
    $F1{$id} = $value;
}

open my $f2, '<', shift or die $!;
while (<$f2>) {
    my ($val0, $val1, $val2, $id) = split;
    print join ' ', $val0, $val1, $val2, $id,
        $F1{$id} x exists $F1{$id}, "\n";
}

Сохранить как match-cols, запустить как perl match-cols file1 file2.

Сохраняет значения из файла 1 в хэш-карте, затем читает файл2 строка за строкой и выводит либо саму строку, если идентификатор не найден в хэш-карте, либо строку плюс информацию, хранящуюся в хэш-карте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...