从每一行中提取特定字符

从每一行中提取特定字符

我有一个文本文件,我想从后面的每一行中提取字符串"OS="

input file line
A0A0A9PBI3_ARUDO Uncharacterized protein OS=Arundo donax OX=35708 PE=4 SV=1
K3Y356_SETIT ATP-dependent DNA helicase OS=Setaria italica OX=4555 PE=3 SV=1

所需输出

OS=Arundo donax
OS=Setaria italica

或者

Arundo donax
Setaria italica

答案1

使用带有扩展正则表达式的 GNU grep(或兼容版本):

grep -Eo "OS=\w+ \w+" file

或基本正则表达式(你需要转义+

grep -o "OS=\w\+ \w\+" file
# or
grep -o "OS=\w* \w*" file

要获得从OS=到 的所有内容,OX=您可以使用grep与 perl 兼容的正则表达式(PCRE)(-P选项)(如果可用)并进行前瞻:

grep -Po "OS=.*(?=OX=)" file

#to also leave out "OS="
#use lookbehind
grep -Po "(?<=OS=).*(?=OX=)" file
#or Keep-out \K
grep -Po "OS=\K.*(?=OX=)" file

或者使用grep包含OX=并随后删除它sed

grep -o "OS=.*\( OX=\)" file | sed 's/ OX=$//'

输出:

OS=Arundo donax
OS=Setaria italica

答案2

在 Perl 中,两个非空白“单词”:

$ perl -lne 'print $1 if /OS=(\S+ \S+)/' input

或以下所有内容OX=

$ perl -lne 'print $1 if /OS=(.*?) OX=/' input 

或接下来的一切something=

$ perl -lne 'print $1 if /OS=(.*?) (\w+)=/' input

对于您的示例输入,它们都给出相同的输出,但输出会有所不同,例如这样的输入:

ABC=something here OS=foo bar doo PE=3 OX=1234

答案3

更可靠的方法是使用 sed 解析完整值,直到找到包含下一个 = 的单词。这样,它将适用于任何大小的值(例如,如果您的字体包含一个单词或三个单词)。

sed 's/.*OS=\([^=]*\).*/\1/;s/ [^ ]*$//'

第一个块捕获 之前的所有内容OS=,捕获组中的第二个块(用\(\)'s 表示)与下一个块匹配=,并且可以在替换中将其称为\1。下一次替换将删除最后一个单词,该单词是下一次分配的片段。

注意:^in[]是排除匹配字符,在这种情况下是所有内容不是一个=标志。

答案4

awk '{print $(NF-4), $(NF-3)}' file

OS=Arundo donax
OS=Setaria italica 

或者

awk -F= '{sub(/OX/,""); print $(NF-3)}' file 

Arundo donax 
Setaria italica

相关内容