我想找到一个特定的模式(k__
)以及它之后的任何字符(直到空格),然后将捕获的模式移动到行尾
使用此示例文件:
cat test.file
37099 k__Eukaryota species:s__Isochrysis galbana;genus:g__Isochrysis;family:f__Isochrysidaceae;order:o__Isochrysidales;class:c__Haptophyta;phylum:p__Haptista
73015 k__Eukaryota species:s__Monodus sp. CCMP505;genus:g__Monodus;family:f__Pleurochloridaceae;order:o__Mischococcales;class:c__Xanthophyceae;phylum:p__
73015 k__Eukaryota species:s__Monodus sp. CCMP505;genus:g__Monodus;family:f__Pleurochloridaceae;order:o__Mischococcales;class:c__Xanthophyceae;phylum:p__
73015 k__Eukaryota species:s__Monodus sp. CCMP505;genus:g__Monodus;family:f__Pleurochloridaceae;order:o__Mischococcales;class:c__Xanthophyceae;phylum:p__
73015 k__Eukaryota species:s__Monodus sp. CCMP505;genus:g__Monodus;family:f__Pleurochloridaceae;order:o__Mischococcales;class:c__Xanthophyceae;phylum:p__
73015 k__Eukaryota species:s__Monodus sp. CCMP505;genus:g__Monodus;family:f__Pleurochloridaceae;order:o__Mischococcales;class:c__Xanthophyceae;phylum:p__
43925 k__Eukaryota species:s__Nannochloropsis oculata;genus:g__Nannochloropsis;family:f__Monodopsidaceae;order:o__Eustigmatales;class:c__Eustigmatophyceae;phylum:p__
43925 k__Eukaryota species:s__Nannochloropsis oculata;genus:g__Nannochloropsis;family:f__Monodopsidaceae;order:o__Eustigmatales;class:c__Eustigmatophyceae;phylum:p__
43925 k__Eukaryota species:s__Nannochloropsis oculata;genus:g__Nannochloropsis;family:f__Monodopsidaceae;order:o__Eustigmatales;class:c__Eustigmatophyceae;phylum:p__
43925 k__Bacteria species:s__Nannochloropsis oculata;genus:g__Nannochloropsis;family:f__Monodopsidaceae;order:o__Eustigmatales;class:c__Eustigmatophyceae;phylum:p__
因此,我想匹配k__Eukaryota
和k__Bacteria
(以及以 开头的其他模式k__
),然后将捕获的匹配项移动到行尾。所需输出:
37099 species:s__Isochrysis galbana;genus:g__Isochrysis;family:f__Isochrysidaceae;order:o__Isochrysidales;class:c__Haptophyta;phylum:p__Haptista k__Eukaryota
73015 species:s__Monodus sp. CCMP505;genus:g__Monodus;family:f__Pleurochloridaceae;order:o__Mischococcales;class:c__Xanthophyceae;phylum:p__ k__Eukaryota
73015 species:s__Monodus sp. CCMP505;genus:g__Monodus;family:f__Pleurochloridaceae;order:o__Mischococcales;class:c__Xanthophyceae;phylum:p__ k__Eukaryota
73015 species:s__Monodus sp. CCMP505;genus:g__Monodus;family:f__Pleurochloridaceae;order:o__Mischococcales;class:c__Xanthophyceae;phylum:p__ k__Eukaryota
73015 species:s__Monodus sp. CCMP505;genus:g__Monodus;family:f__Pleurochloridaceae;order:o__Mischococcales;class:c__Xanthophyceae;phylum:p__ k__Eukaryota
73015 species:s__Monodus sp. CCMP505;genus:g__Monodus;family:f__Pleurochloridaceae;order:o__Mischococcales;class:c__Xanthophyceae;phylum:p__ k__Eukaryota
43925 species:s__Nannochloropsis oculata;genus:g__Nannochloropsis;family:f__Monodopsidaceae;order:o__Eustigmatales;class:c__Eustigmatophyceae;phylum:p__ k__Eukaryota
43925 species:s__Nannochloropsis oculata;genus:g__Nannochloropsis;family:f__Monodopsidaceae;order:o__Eustigmatales;class:c__Eustigmatophyceae;phylum:p__ k__Eukaryota
43925 species:s__Nannochloropsis oculata;genus:g__Nannochloropsis;family:f__Monodopsidaceae;order:o__Eustigmatales;class:c__Eustigmatophyceae;phylum:p__ k__Eukaryota
43925 species:s__Nannochloropsis oculata;genus:g__Nannochloropsis;family:f__Monodopsidaceae;order:o__Eustigmatales;class:c__Eustigmatophyceae;phylum:p__ k__Bacteria
我以为这很容易,但我做不到。以下是我尝试过的方法:
cat test.file | gsed -E 's#(.*k__)(k__\w\+)(.*)#\1\3\2#'
捕获文本直到模式,然后匹配(捕获模式和任何单词字符直到空格)然后捕获到行尾,然后更改捕获组的顺序。
我认为我可以反向引用这些模式来更改顺序,但我可能没有正确匹配它们。如何捕获我的模式,模式 ( k__xyz
),然后匹配到行尾,捕获这些组并重新组织?这是正确的方法吗?
答案1
主要s#(.*k__)(k__\w\+)(.*)#\1\3\2#
问题是第一个捕获组需要k__
,第二个捕获组需要还需要。您的文件每行k__
包含一个。k__
由于您希望k__
与相邻文本一起移动到行尾,因此它应该属于第二组。在第一组中,有一个名为积极展望可用于确保k__
之后正确。sed
不支持该功能,但这里实际上不需要它。第二个捕获组紧跟在第一个捕获组之后,并且需要k__
。
修复命令的最简单方法是k__
从第一组中删除:
<test.file gsed -E 's#(.*)(k__\w+)(.*)#\1\3 \2#'
注意我使用了+
而不是 ,\+
因为这sed
在我的 Debian 中的 GNU 中有效。我还在\3
和之间添加了一个空格\2
(另一种选择是:s#(.*)( k__\w+)(.*)#\1\3\2#
,因此您不会在前导数字后得到四个空格;但您想要的文本确实在那里指定了四个空格)。
一个潜在的问题是第一组是贪婪的。当一行中.*
只有一个时,这是可以的;否则第二组可能会匹配一些稍后的。至少有两个解决方案:k__
k__
- 简单的非贪婪匹配:一般来说
.*?
,但不是sed
; - 第一组中更具体的模式,在您的情况下该组可能是
( *[0123456789]+ *)
。
附注:为什么<test.file
不是cat test.file |
?请参阅后半部分我的这个答案。