sed命令的解释

sed命令的解释

我发现这个有趣的命令:

grep -v '^>' test.fasta | tr -d '\n' | sed -e 's/\(.\)/\1\n/g' | sort | uniq -c | sort -rn

我对它的含义有所了解(它计算文本文件中的字母),但我的问题是这样的:

sed -e 's/\(.\)/\1\n/g'

我知道它由三个替代命令组成。一种是替换换行符(\n),即匹配除换行符(\(.\))之外的任何字符,但我迷失了/\1\

答案1

命令

sed -e 's/\(.\)/\1\n/g'

是一个 GNUsed替换命令,它将每个字符替换为自身,后跟换行符。这样做的效果是将输入折叠成单个字符的单列。

$ echo hello | sed -e 's/\(.\)/\1\n/g'
h
e
l
l
o

\(.\)是一个“捕获组”,捕获单个字符。这\1是对第一个捕获组的“反向引用”。\1在替换文本中使用将插入第一个括号捕获的任何内容。

它也可以写成没有那么多反斜杠,例如

sed 's/./&\n/g'

其中&仅表示“表达式匹配的任何内容”。

sed命令要求 GNUsed作为标准,sed不能\n像这样插入换行符。

要使用标准工具更有效地完成此操作,请使用

fold -w 1

反而。这更有效,因为输入中的每个字符不需要正则表达式匹配。

使用fold,您的管道可以编写

grep -v '^>' file | tr -d '\n' | fold -w 1 | sort | uniq -c | sort -rn

或者,使用awk来摆脱该管道的几个步骤,

awk '!/^>/ { for (i = 1; i <= length; ++i) count[substr($0,i,1)]++ }
    END { for (ch in count) print count[ch], ch }' file |
sort -rn

awk代码计算每个字符出现的次数。它通过递增count与输入流中的每个字符对应的数组中的值来实现这一点。输入结束时,输出计数和字符计数的摘要。

答案2

我希望这能让事情变得更清楚。

“我知道它是由三个替代命令组成的”

这只是一个替代命令(如果您指的是该sed命令):,s/<pattern to search>/<replacement>/它将执行以下命令:

  • 对于每一行搜索<pattern>并将其替换为<replacement>
  • 国旗g的意思是做吧G全局性的,因为默认情况下sed仅替换第一次出现的<pattern>.

“但我迷失了/\1\

\(<pattern>\)您可以通过使用转义括号或仅使用选项括起来来捕获模式-E(<pattern>)

在本<replacement>节中,捕获的模式由反斜杠和数字 引用\<number>。该数字指的是捕获的位置,因为您可以有多个:

sed -E '/(<first capture>)(<second capture>)/\1\2/'

所以该命令的sed -e 's/\(.\)/\1\n/g'意思是:

  • 捕获每个字符\(.\)并用其自身和新行替换它\1\n
  • 使用g,全局执行,不要在第一次出现时停止。

例如:

$ echo foo | sed -E 's/(.)/\1\n/g'
f
o
o


-e此处不需要这些选项,除非您要连接多个sed命令:sed -e '...' -e '...'等。


您可以在以下位置找到更多信息:反向引用和子表达式

答案3

使用 Raku(以前称为 Perl_6)

raku -e 'for lines.grep({ !/ ^ \> / }).join { .say for .comb.Bag.sort(*.values).reverse};'

输入示例:

>sp|P01308|INS_HUMAN Insulin OS=Homo sapiens OX=9606 GN=INS PE=1 SV=1
MALWMRLLPLLALLALWGPDPAAAFVNQHLCGSHLVEALYLVCGERGFFYTPKTRREAED
LQVGQVELGGGPGAGSLQPLALEGSLQKRGIVEQCCTSICSLYQLENYCN

示例输出:

L => 20
G => 12
A => 10
E => 8
Q => 7
P => 6
C => 6
V => 6
R => 5
S => 5
Y => 4
F => 3
T => 3
N => 3
M => 2
D => 2
K => 2
I => 2
W => 2
H => 2

您提供的代码可以用多种语言(不仅仅是sed)编写,其中任何一种都可能引起您的共鸣。例如,上面的代码已用 Raku(Perl 语言家族的成员)重新编写。

大多数 Raku 代码应该是相当不言自明的:lines读入,并grep-ped 表示!缺少^行首>“大于”角度,并join-ed。连接的行是comb-ed (分成单独的字符),Bag-ged (每个出现的字符变成 akey并且出现次数被计数/记录为values),sort-ed inreverse首先放置最高的出现次数,然后用 打印say

https://raku.org

相关内容