我有两个文件genelist.txt
和data.txt
.genelist.txt
仅包含一列约 500 个基因名称,而data.txt
是一个制表符分隔文件,包含约 1000 列(样本)和约 30,000 行(基因名称)。总体方案data.txt
概述如下。
Sample 1 Sample 2 Sample 3 Sample 4 Gene A 1.04 1.81 1.92 0.45 Gene B 1.11 1.12 1.32 0.92 Gene C 0.72 0.71 0.85 1.12 Gene D 1.19 1.42 0.13 0.32
我需要从data.txt
包含大约 500 个基因名称的每一个中提取每一行(整行,即所有样本) genelist.txt
,并将这些行提取到一个单独的文件中。我被告知使用 grep 或 awk 并研究了如何执行此操作,但是作为一个几乎没有编码经验的简单生物学家,我遇到了一些麻烦。有人可以解释这是如何完成的吗,并希望为我提供一些代码来开始。
如果提取仅返回与 中整个基因名称匹配的术语,那就太好了genelist.txt
。例如,如果我有ABC123但不是ABC1234中genelist.txt
,我只想ABC123被提取而不是被提取ABC1234。
此外,完成此操作后,我该如何检查哪些基因未genelist.txt
包含在提取中?(即某些基因可能命名错误,因此我必须返回并使用替代名称和/或正确名称重新提取它们)。
答案1
data.txt
要从中列出的基因中提取行genelist.txt
:
grep -w -F -f genelist.txt data.txt > newdata.txt
grep
使用的选项:
-w
告诉grep
仅匹配整个单词(即 soABC123
也不会匹配ABC1234
)。-F
搜索固定字符串(纯文本)而不是正则表达式-f genelist.txt
从文件中读取搜索模式
如果您还需要标题行(示例 1、示例 2 等):
grep -w -F -f genelist.txt -e Sample data.txt > newdata.txt
-e Sample
还可以搜索“样本”
要查找 中genelist.txt
不存在的行newdata.txt
:
grep -v -w -F -f <(sed -E -e 's/(\t| +).*//' newdata.txt) genelist.txt
-v
反转搜索,打印不匹配的行。
grep 选项的其余部分是相同的,但它不是使用带有该选项的文件-f
,而是使用名为流程替代(看还),它允许您使用命令代替实际文件。该命令创建的任何输出都被视为“文件”的内容。
在本例中,我们使用命令sed -E -e 's/(\t| +).*//' newdata.txt
,该命令在首先删除第一个 TAB 字符或它看到的第一对空格中的所有内容后输出 newdata.txt 的每一行。换句话说,第一个字段(例如“基因 A”)。我必须使用 TAB 或双空格,因为 a) 我不确定您的数据是空格分隔还是 TAB 分隔,b) 示例中的第一个字段包含空格。
sed
使用的选项:
-E
使用扩展正则表达式,因此我们可以使用普通的(
,)
, 和 ,这比使用as , ,+
转义它们更具可读性。\
\(
\)
\+
-e 's/(\t| +).*//'
指定要应用于输入的 sed 脚本 (newdata.txt)
在您的示例上运行该命令data.txt
将产生以下输出:
$ sed -E -e 's/(\t| +).*//' data.txt
Gene A
Gene B
Gene C
Gene D
无论如何,该命令的输出sed
将用作该grep
命令的搜索模式列表。
答案2
实际回答你的问题:
fgrep -w -f genelist.txt data.txt >results.txt
fgrep
查找固定字符串,而不是正则表达式(asgrep
和egrep
do)-w
告诉fgrep
要匹配整个单词,所以ABC123
不会匹配ABC1234
-f genelist.txt
告诉fgrep
从 读取搜索模式genelist.txt
。
查看哪些基因genelist.txt
未包含在提取中有点复杂。一种方法是:
awk '{ print $1 }' results.txt | fgrep -w -v -f - genelist.txt >outsiders.txt
awk '{ print $1 }'
打印文本文件中的第一列;这些是匹配基因的列表fgrep
再次匹配固定字符串-w
告诉fgrep
匹配整个单词-v
告诉它打印以下行不匹配-f -
告诉它从 读取模式列表stdin
,即来自 的匹配基因列表awk
。
sort -u
您还可以通过在搜索之前从匹配基因列表中消除重复项,通过在awk
和之间进行调解来提高效率fgrep
:
awk '{ print $1 }' results.txt | sort -u | fgrep -w -v -f - genelist.txt >outsiders.txt
答案3
对于没有任何 Linux 经验的人来说,这是一项艰巨的任务。不过,我想我明白你需要什么,而且应该不会太难。请提前原谅我,除了非常基本的解释之外,这是一个非常简洁的速成课程,但如果它没有意义,我很乐意详细说明,或根据需要进行编辑。
如果您只想解析data.txt
并将其移动到genelist.txt
您可以简单地使用cat data.txt >> genelist.txt newfile.txt
. (newfile.txt 是您提到的另一个文件 - 名称是任意的)。
如果您想打印特定名称的行,您可以使用cat data.txt | grep ABCD123 >> genelist.txt newfile.txt
ABCD123 并将其更改为您想要的任何内容。
此命令将仅输出使用 grep 找到的行(有点像“搜索”功能,但它仅按行搜索。)
“|”称为管道,当与“grep”命令结合使用时,它的作用有点像过滤器,可以过滤您要查找的内容。 (cat zoofile.txt | grep pandas
例如,将查找包含单词“pandas”的所有行,即文件名“zoofile”。注意 Linux 区分大小写,只会准确找到您输入的内容。如果您想要“panda、pandas、panderoons”的所有实例或迎合,您可以使用 pand*,其中 * 是通配符,长度可以是 0 到 255 位之间的任何字符,这将拾取 pand 到 pandzzzzzzzzzz 以及介于两者之间的任何字符,包括数字)。
您可以使用 awk 进行更奇特的列解析(它是我最喜欢的工具之一!),但它似乎不适合这里,除非您只需要基于某些参数的列之一的数据。
最后,这里是学习一些命令行知识的好地方。这可能对 grep 有帮助,但不包括 awk。
https://www.codecademy.com/learn/learn-the-command-line
之后,这应该更详细地介绍 awk。关于 awk 有很多非常广泛的课程,但它们很容易迷失。这是一个实用的网站,可以更多地演示您想要做的事情。
https://www.ibm.com/developerworks/library/l-awk1/
编辑 - 重新阅读后,我可能错过了一些东西 - 您是否想要比较两个文件并仅打印出一个与另一个文件匹配的内容?请提供建议并提供示例,我很乐意相应地编辑我的答案。