基本 grep/awk 帮助 - 将包含术语列表的所有行从一个文件提取到一个单独的文件中

基本 grep/awk 帮助 - 将包含术语列表的所有行从一个文件提取到一个单独的文件中

我有两个文件genelist.txtdata.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但不是ABC1234genelist.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查找固定字符串,而不是正则表达式(asgrepegrepdo)
  • -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.txtABCD123 并将其更改为您想要的任何内容。

此命令将仅输出使用 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/

编辑 - 重新阅读后,我可能错过了一些东西 - 您是否想要比较两个文件并仅打印出一个与另一个文件匹配的内容?请提供建议并提供示例,我很乐意相应地编辑我的答案。

相关内容