Сравните первые столбцы из двух файлов. Если совпадают, транспонируйте значения для той же записи из FILE2 в FILE1. Если совпадений не найдено, заполните "NA"

< Сильный > FILE1

123 B
124 A
125 N
129 C
134 B
141 T
167 8
179 5

< Сильный > FILE2

123 1 1
123 2 1
124 1 3
124 2 3
129 6 1
129 7 1
134 5 1
134 9 1
167 8 2
167 8 2

Desired Output

123 B 1 2 1
124 A 1 2 3
125 N NA
129 C 6 7 1
134 B 5 9 1
141 T NA
167 8 8 8 2
179 5 NA

Я использовал этот код для отсутствующих записей, но все еще не могу транспонировать строки для найденных записей:

awk 'NR==FNR{a[$1]=$2;next;}{print $0 "    " ($1 in a ? a[$1] : "NA")}' FILE2 FILE1

123 B    2
124 A    2
125 N    NA
129 C    7
134 B    9
141 T    NA
167 8    8
179 5    NA

Заранее спасибо

awk
0
OXXO 21 Авг 2018 в 15:20

3 ответа

Лучший ответ

Я предполагаю, что вы хотите собрать список 2-го столбца file2, но сохранить только последнее значение 3-го столбца file2.

Вот немного Perl:

perl -lane '
    if ($. == ++$nr) {
        $x{$F[0]} = $F[1];
    } else {
        push @{ $y{$F[0]} }, $F[1];
        $z{$F[0]} = $F[2];
    }
    close ARGV if eof; # reset $. for new file
    END {
        for $key (sort keys %x) {
            printf "%s %s %s\n", $key, $x{$key},
                (exists $y{$key} ? join(" ", @{$y{$key}}, $z{$key}) : "NA");
        }
    }
' file 1 file2
123 B 1 2 1
124 A 1 2 3
125 N NA
129 C 6 7 1
134 B 5 9 1
141 T NA
167 8 8 8 2
179 5 NA

Как awk

gawk '
    NR == FNR {
        x[$1] = $2
        next
    }
    {
        y[$1] = y[$1] $2 OFS
        z[$1] = $3
    }
    END {
        PROCINFO["sorted_in"] = "@ind_num_asc"
        for (key in x) {
            printf "%s %s %s\n", key, x[key], (key in y ? y[key] z[key] : "NA")
        }
    }
' file{1,2}

Это использует GNU awk только для переменной PROCINFO. Если вы не хотите эту зависимость, просто удалите эту строку и направьте вывод в | sort -k1,1n

1
glenn jackman 21 Авг 2018 в 15:14

На основе текущего описания и примера ввода в вопросе этот код awk работает:

 awk 'NR==FNR{a[$1]=$2 FS $3 FS $4;next}{print $0,($1 in a?a[$1]:"NA")}' <(awk 'NR%2{printf "%s",$1 FS $2 FS;next}{print $2,$3}' FILE2) FILE1

Для лучшего чтения:

 awk 'NR==FNR{a[$1]=$2 FS $3 FS $4;next}
      {print $0,($1 in a?a[$1]:"NA")}' 
<(awk 'NR%2{printf "%s",$1 FS $2 FS;next}{print $2,$3}' FILE2)  
FILE1

С вашими данными испытаний:

kent$  head f f2
==> f <==
123 B
124 A
125 N
129 C
134 B
141 T
167 8
179 5

==> f2 <==
123 1 1
123 2 1
124 1 3
124 2 3
129 6 1
129 7 1
134 5 1
134 9 1
167 8 2
167 8 2

kent$  awk 'NR==FNR{a[$1]=$2 FS $3 FS $4;next}{print $0,($1 in a?a[$1]:"NA");}' <(awk 'NR%2{printf "%s",$1 FS $2 FS;next}{print $2,$3}' f2) f
123 B 1 2 1
124 A 1 2 3
125 N NA
129 C 6 7 1
134 B 5 9 1
141 T NA
167 8 8 8 2
179 5 NA
1
Kent 21 Авг 2018 в 12:45

Не могли бы вы попробовать следующее.

awk '
FNR==NR{
  if(++b[$1]==1){
    a[$1]=$2
  }
  else{
    a[$1]=a[$1] OFS $2 OFS $3
  }
  next
}
($1 in a){
  print $1,$2,a[$1]
  next
}
{
  print $0,"NA"
}' Input_file2  Input_file1

Результат будет следующим.

123 B 1 2 1
124 A 1 2 3
125 N NA
129 C 6 7 1
134 B 5 9 1
141 T NA
167 8 8 8 2
179 5 NA
1
RavinderSingh13 21 Авг 2018 в 12:53
51948559