我有一个看起来像这样的文件:
chr1 3143567 3143568 .3-2704 1.000000|ENSMUSG00000102693.2
chr1 3143599 3143600 .3-2705 1.000000|ENSMUSG00000102693.2
chr1 3143631 3143632 .3-2706 1.000000|ENSMUSG00000102693.2
chr1 3143663 3143664 .3-2707 1.000000|ENSMUSG00000102693.2
chr1 3143695 3143696 .3-2708 1.000000|ENSMUSG00000102693.2
chr1 3143727 3143728 .3-2709 1.000000|ENSMUSG00000102693.2
我正在编写 2 个 sed 表达式来过滤|
第一个表达式之前的所有内容,并且对于结果文件,我会丢弃之后的所有内容,如下.
所示:
sed -n -e 's/^.*|//p' original_file.txt > first_result.txt
sed -n -e 's/\..*//p' first_result.txt > final_result.txt
我怎样才能将所有这些写在一行中?
最终目标是捕获ENSMUSG00000102693
答案1
您的命令将丢弃不包含|
字符的行以及鼠标基因标识符没有版本号的行。我不确定这是有意的,但这是sed -n
与命令p
上的标志一起使用的副作用s
。我假设这是无意的。
只需使用两个表达式sed
:
sed -e 's/.*|//' -e 's/\..*//' file >newfile
使用grep
具有非标准-o
选项的命令,并假设您只想从文件中提取所有 Ensembl 小鼠基因稳定 ID(并且该文件仅包含您想要提取的稳定 ID),
grep -o 'ENSMUSG[[:digit:]]*' file >newfile
您还可以使用两个链接cut
命令,每个命令都会对数据进行与sed
本答案前面的两个替换类似的修改。使用静态剪切可能比使用正则表达式更快,但我怀疑除非您的输入数据很大,否则您不会看到任何重大的速度差异。
cut -d '|' -f 2 file | cut -d '.' -f 1 >newfile
答案2
您可以使用 GNU grep
(看起来比 GNU 的性能稍好一些sed
):
$ grep -Po '(?<=\|)[^|.]+' first_result.txt
ENSMUSG00000102693
ENSMUSG00000102693
ENSMUSG00000102693
ENSMUSG00000102693
ENSMUSG00000102693
ENSMUSG00000102693
- 该模式的
(?<=\|)[^|.]+
意思是“查找从首字母( ) 开始(并排除)的所有不是 a|
或.
( ) 的字符”。[^|.]+
|
(?<=\|)
和sed
:
$ sed 's/.*|\([^|]\+\)\..*/\1/' first_result.txt
ENSMUSG00000102693
ENSMUSG00000102693
ENSMUSG00000102693
ENSMUSG00000102693
ENSMUSG00000102693
ENSMUSG00000102693
- 该模式的意思是“删除和( , )
.*|\([^|]\+\)\..*
之间的所有字符并捕获 ( ) 之间的内容,最后用捕获的模式 ( ) 替换所有字符。|
.
.*|
\..*
\([^|]\+\)
/\1/
或者更简洁地说:
$ sed -E 's/.*\|([^|]+)\..*/\1/'
答案3
您可以使用如下所示的单个sed
表达式。将所有内容匹配到最后一个|
以忽略,然后捕获最后一个之前的部分.
并将其排除在结果中。在任何支持 POSIX BRE 的 sed 上
sed 's/.*|\([^.]*\)\..*/\1/'
如果首选 awk,
awk -F'[|.]' '{ print $(NF-1) }'