Как выбрать совпадающие данные из двух файлов в Linux? - PullRequest
0 голосов
/ 25 февраля 2019

У меня есть 2 файла со списками генов (и оба файла с другими столбцами, которые содержат различную информацию в списках генов). Я ищу, чтобы определить гены, которые появляются в обоих файлах, и взять информацию о соответствующих генах из обоих файлов, чтобы поместить вновый файл.

Например, данные выглядят так:

File 1
Gene   P value
ACT      0.1
BRCA     0.3
AGT      0.004
UMOD     0.05

File 2
Gene    Tissue
MTHFR   Heart
UMOD.1  Kidney
TP53    Lung
ACT     Lung

Я пытаюсь получить вывод, подобный этому:

Gene   P value    Tissue
UMOD   0.05       Kidney
ACT    0.1        Lung

У меня есть одна проблемав том, что в одном файле есть совпадающие гены, но с дополнительными номерами (например, UMOD против UMOD.1), поэтому, даже если они совпадают, ген не совпадает с именем гена.соответствующие гены, которые я пробовал:

cat file1.txt|grep -f file2.txt > temp.txt

но временный файл пуст, я не уверен, почему это не сработало или что нужно сделать, чтобы получить мой вывод, любая помощь будет оценена.

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

awk 'BEGIN{FS=OFS="\t"} FNR==1{print;next} {if($1==file2.txt $1) print printf $i""FS; print ""}'  file1txt > temp.txt

Ответы [ 3 ]

0 голосов
/ 25 февраля 2019

Вы можете сделать это с join.В следующих примерах игнорируется .1 в имени гена и не предполагается никаких заголовков, например:

join <(sort file1) <(sort file2)

Вывод:

ACT 0.1 Lung
UMOD 0.05 Kidney
0 голосов
/ 25 февраля 2019

Еще один awk (почти такой же, как у @ RavinderSingh13 (++), но с использованием split и обратным порядком файлов для захвата P value в выводе заголовка без определения FS=OFS="\t"):

$ awk '{
    split($1,k,".")         # split $1 on . and store first part to k[1]
}
NR==FNR {
    a[k[1]]=$2              # hash $2 of file2 in a hash, k[1] as key
    next
}
k[1] in a {                 # if k[1] from file1 is found in a hash
    print $0 "\t" a[k[1]]   # output tab-separated
}' file2 file1              # file order reversed 

Вывод:

Gene    P value Tissue
ACT     0.1     Lung
UMOD    0.05    Kidney

Редактировать:

Когда файлы имеют больше полей, чем представлено в OP:

$ cat file1
Gene    P value field13
ACT     0.1     val11
BRCA    0.3     val12
AGT     0.004   val13
UMOD    0.05    val14
$ cat file2
Gene    Tissue  field23
MTHFR   Heart   val21
UMOD.1  Kidney  val22
TP53    Lung    val23
ACT     Lung    val24

Awk:

$ awk 'BEGIN {
    FS=OFS="\t"             # This solution requires field separators set
}
{
    split($1,k,".")         # split $1 on . and store first part (the key) to k[1]
}
NR==FNR {
    $1=""                   # remove unneeded key field from $0
    a[k[1]]=$0              # hash $0 of file2 in a hash, k[1] as key
    next
}
k[1] in a {                 # if k[1] from file1 is found in a hash
    print $0 a[k[1]]        # output tab-separated
}' file2 file1              # file order reversed

Выход:

Gene    P value field13 Tissue  field23
ACT     0.1     val11   Lung    val24
UMOD    0.05    val14   Kidney  val22
0 голосов
/ 25 февраля 2019

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

awk '{sub(/\.[0-9]+$/,"",$1)} FNR==NR{a[$1]=$1 OFS $2;next} $1 in a{print a[$1],$NF}'  file1  file2

Что касается OP, то в Input_file1 может быть много полей, и OP может понадобиться их немного, поэтому я предполагаю, что допустим, скажем, OP имеет 15 полей вInput_file1 и нужно 14 из них, сначала 14, если это так, то может помочь следующее (поскольку выборки нет, поэтому не проверял, но это должно работать)

awk '{sub(/\.[0-9]+$/,"",$1)} FNR==NR{$15="";sub(/[[:space:]]+$/,"");a[$1]=$0;next} $1 in a{print a[$1],$NF}'  file1  file2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...