Почему использование awk в bash, как vlookup в Excel, дает пустой выходной файл? - PullRequest
1 голос
/ 09 мая 2019

Хорошее использование awk все еще неясно для меня, но я знаю, что это будет полезно для того, что я хочу.

У меня есть два файла, оба с разделителями табуляции:

transcriptome.txt (с миллиардом строк):

 >TRINITY_DN261_c0_g1_i1    GATATTTATCCGAATATTCAATATGAT
 >TRINITY_DN299_c0_g1_i1    GGACACGGGCCTCAAGCCAAGTCAAAACCACCACAAAG
 >TRINITY_DN216_c0_g1_i1    GTTCAATATTCAATGACTGAAGGGCCCGCTGATTTTCCCCTATAAA
 >TRINITY_DN220_c0_g1_i1    GGGAGATAATAACAATGATAACACACAAAATTCCAATG

selected_genes.txt (тысячи строк):

 >TRINITY_DN261_c0_g1_i1    1
 >TRINITY_DN220_c0_g1_i1    0

Я хочу этот вывод (первый столбец selected_genes.txt и второй столбец transcriptome.txt):

 >TRINITY_DN261_c0_g1_i1    GATATTTATCCGAATATTCAATATGAT
 >TRINITY_DN220_c0_g1_i1    GGGAGATAATAACAATGATAACACACAAAATTCCAATG

Обычно я использую функцию vlookup в Excel. Я пытаюсь получить результат с awk, как во многих потоках ( stackexchange1 , stackexchange2 , stackoverflow1 , stackoverflow2 , stackoverflow3 и другие ..)

Поэтому я попытался использовать советы из этих тем, но мой вывод либо пуст, либо это только копия моего selected_genes.txt файла.

Я проверил, мои 2 файла в UTF-8, с CRLF. Кроме того,

awk '{print $1}' `transcriptome.txt`
awk '{print $1}' `selected_genes.txt`

Дайте мне первый столбец моих файлов, чтобы проблема не возникла из них.

Вот что я попробовал:

awk -F, 'FNR==NR {a[$1]=$1; next}; $1 in a {print a[$2]}' selected_genes.txt transcriptome.txt > output.txt
# Blank result

awk -F 'FNR==NR{var[$1]=$1;next;}{print var[$1]FS$2}' selected_genes.txt transcriptome.txt > output.txt
# Blank result

awk 'NR == FNR{a[$1] = $2;next}; {print $1, $1 in a?a[$1]: "NA"}' selected_genes.txt transcriptome.txt > output.txt
# Print only transcriptome.txt with first column and NAs

awk -F, 'FNR==NR{var[$1]=$1}FNR!=NR{print(var[$2]","$1)}' selected_genes.txt transcriptome.txt > output.txt
# Print only selected_genes.txt

Я не смог добиться желаемого результата. Любые советы, которые объяснят мне, в чем проблема с моим кодом, будут благодарны.

Ответы [ 3 ]

2 голосов
/ 09 мая 2019

Классик Awk. Хэш-файл тысячи строк в хэш (a), чтобы не тратить всю память и поиск $1 из миллиардов строк файл транскриптом:

$ awk '
    # { sub(/\r$/,"") }    # uncomment to remove Windows style line-endings.
    NR==FNR{a[$1]          # hash $1 of genes file to a
    next
}
($1 in a) {                # lookup from transcriptome
    print
}' genes transcriptome     # mind the order
>TRINITY_DN261_c0_g1_i1    GATATTTATCCGAATATTCAATATGAT
>TRINITY_DN220_c0_g1_i1    GGGAGATAATAACAATGATAACACACAAAATTCCAATG
0 голосов
/ 09 мая 2019

ваш код:

awk -F, 'FNR==NR{a[$1]=$1; next}; $1 in a {print a[$2]}' 

не будет работать, так как вы пытаетесь напечатать a[$2], который не существует.

Измените на

awk -F, 'FNR==NR{a[$1]; next} $1 in a' selected_genes.txt transcriptome.txt 

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

Второе выражение сокращенно для ($1 in a) {print $0}

0 голосов
/ 09 мая 2019

В коробке есть лучший инструмент, чем awk для такого слияния файлов в общем поле, особенно для больших файлов: join (1)

$ join -t $'\t' -11 -21 -o 0,2.2 \
   <(sort -t $'\t' -k1,1 selected_genes.txt) \
   <(sort -t $'\t' -k1,1 transcriptome.txt)
>TRINITY_DN220_c0_g1_i1 GGGAGATAATAACAATGATAACACACAAAATTCCAATG
>TRINITY_DN261_c0_g1_i1 GATATTTATCCGAATATTCAATATGAT

Единственное предостережение заключается в том, что файлы, которые нужно объединить, должны быть отсортированы по столбцу объединения, следовательно, используется sort.

В терминах базы данных он делает INNER JOIN из двух файлов - для каждой строкипервого файла, каждая строка второго файла с соответствующим столбцом соединения приводит к одной строке вывода.-o 0,2.2 делает эти строки столбцом соединения и вторым столбцом второго файла.


Еще одна интересная опция:

$ grep -F -f <(sed -e 's/[^\t]*$//' selected_genes.txt) transcriptome.txt 
>TRINITY_DN261_c0_g1_i1 GATATTTATCCGAATATTCAATATGAT
>TRINITY_DN220_c0_g1_i1 GGGAGATAATAACAATGATAACACACAAAATTCCAATG

будет, очень эффективно , показать только строки transcriptome.txt, в которых есть первый столбец строки в selected_genes.txt.Это быстрее, чем другие подходы с большим отрывом в моих тестах.

...