为什么在 bash 中使用 awk 就像在 Excel 中使用 vlookup 一样给出空输出文件?
Why using awk in bash like vlookup in Excel give empty output file?
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
通常我在Excel中使用vlookup
函数。
我尝试使用 awk
获得我的结果,就像在许多线程中一样(stackexchange1, stackexchange2, Whosebug1,, Whosebug3,以及其他......)
所以我尝试使用这些线程的建议,但我的输出要么是空白,要么只是我的 selected_genes.txt
文件的副本。
我检查过,我的 2 个文件在 UTF-8
和 CRLF
中。还有,
awk '{print }' `transcriptome.txt`
awk '{print }' `selected_genes.txt`
把我文件的第一列给我,所以问题不是出在他们身上。
这是我尝试过的:
awk -F, 'FNR==NR {a[]=; next}; in a {print a[]}' selected_genes.txt transcriptome.txt > output.txt
# Blank result
awk -F 'FNR==NR{var[]=;next;}{print var[]FS}' selected_genes.txt transcriptome.txt > output.txt
# Blank result
awk 'NR == FNR{a[] = ;next}; {print , in a?a[]: "NA"}' selected_genes.txt transcriptome.txt > output.txt
# Print only transcriptome.txt with first column and NAs
awk -F, 'FNR==NR{var[]=}FNR!=NR{print(var[]",")}' selected_genes.txt transcriptome.txt > output.txt
# Print only selected_genes.txt
我没有实现想要的输出。
任何能解释我的代码有什么问题的建议都将不胜感激。
盒子里有比 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
将 very efficiently 仅显示 transcriptome.txt
中具有 selected_genes.txt
中一行的第一列的行。在我的测试中,这比其他方法快很多。
Awk 经典。将 千行 基因文件散列为一个散列 (a
),以免浪费所有内存并从 十亿行 </code> 中查找 <code>
=17=] 转录组文件:
$ awk '
# { sub(/\r$/,"") } # uncomment to remove Windows style line-endings.
NR==FNR{a[] # hash of genes file to a
next
}
( in a) { # lookup from transcriptome
print
}' genes transcriptome # mind the order
>TRINITY_DN261_c0_g1_i1 GATATTTATCCGAATATTCAATATGAT
>TRINITY_DN220_c0_g1_i1 GGGAGATAATAACAATGATAACACACAAAATTCCAATG
您的代码:
awk -F, 'FNR==NR{a[]=; next}; in a {print a[]}'
将不起作用,因为您正在尝试打印不存在的 a[]
。
改为
awk -F, 'FNR==NR{a[]; next} in a' selected_genes.txt transcriptome.txt
这应该会给你预期的输出
第二个表达式是 shorthand for ( in a) {print [=13=]}
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
通常我在Excel中使用vlookup
函数。
我尝试使用 awk
获得我的结果,就像在许多线程中一样(stackexchange1, stackexchange2, Whosebug1,
所以我尝试使用这些线程的建议,但我的输出要么是空白,要么只是我的 selected_genes.txt
文件的副本。
我检查过,我的 2 个文件在 UTF-8
和 CRLF
中。还有,
awk '{print }' `transcriptome.txt`
awk '{print }' `selected_genes.txt`
把我文件的第一列给我,所以问题不是出在他们身上。
这是我尝试过的:
awk -F, 'FNR==NR {a[]=; next}; in a {print a[]}' selected_genes.txt transcriptome.txt > output.txt
# Blank result
awk -F 'FNR==NR{var[]=;next;}{print var[]FS}' selected_genes.txt transcriptome.txt > output.txt
# Blank result
awk 'NR == FNR{a[] = ;next}; {print , in a?a[]: "NA"}' selected_genes.txt transcriptome.txt > output.txt
# Print only transcriptome.txt with first column and NAs
awk -F, 'FNR==NR{var[]=}FNR!=NR{print(var[]",")}' selected_genes.txt transcriptome.txt > output.txt
# Print only selected_genes.txt
我没有实现想要的输出。 任何能解释我的代码有什么问题的建议都将不胜感激。
盒子里有比 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
将 very efficiently 仅显示 transcriptome.txt
中具有 selected_genes.txt
中一行的第一列的行。在我的测试中,这比其他方法快很多。
Awk 经典。将 千行 基因文件散列为一个散列 (a
),以免浪费所有内存并从 十亿行 </code> 中查找 <code>
=17=] 转录组文件:
$ awk '
# { sub(/\r$/,"") } # uncomment to remove Windows style line-endings.
NR==FNR{a[] # hash of genes file to a
next
}
( in a) { # lookup from transcriptome
print
}' genes transcriptome # mind the order
>TRINITY_DN261_c0_g1_i1 GATATTTATCCGAATATTCAATATGAT
>TRINITY_DN220_c0_g1_i1 GGGAGATAATAACAATGATAACACACAAAATTCCAATG
您的代码:
awk -F, 'FNR==NR{a[]=; next}; in a {print a[]}'
将不起作用,因为您正在尝试打印不存在的 a[]
。
改为
awk -F, 'FNR==NR{a[]; next} in a' selected_genes.txt transcriptome.txt
这应该会给你预期的输出
第二个表达式是 shorthand for ( in a) {print [=13=]}