有没有更健壮的方法来编辑匹配的模式,然后替换它?

iic*_*ich 6 sed awk text-processing

有没有办法编辑匹配的模式,然后用编辑的模式替换另一个模式?

输入:

a11.t
some text here
a06.t
some text here
Run Code Online (Sandbox Code Playgroud)

输出:

a11.t 11
some text here
a06.t 06
some text here
Run Code Online (Sandbox Code Playgroud)

上面的示例显示了前两位数字(与第一个模式匹配)提取并放置在行尾(第二个模式)。

在编程语言中,我会将文件加载到数据结构中,然后编辑、替换并写入新文件。但是有一行等价的吗?

审判:

sed 's/\(a[0-9][0-9].*\)/& \1/I' stack.fa | sed -e 's#a##g2' -e 's#\.\w##g2'
Run Code Online (Sandbox Code Playgroud)

试验输出:

a11.t 11
some text here
a06.t 06
some text here
Run Code Online (Sandbox Code Playgroud)

显然试验是有效的,但有没有更强大的方法?此外,是否有另一种文本处理语言可以更轻松地完成?

ter*_*don 13

尽管它已经过时了,但很少有语言可以在文本处理方面与 perl 相提并论。例如:

  1. 假设只有一组数字,复制到行尾:

     $ perl -pe 's/.*?a(\d+).*/$& $1/' file
     a11.t 11
     some text here
     a06.t 06
     some text here
    
    Run Code Online (Sandbox Code Playgroud)
  2. 多组数字,都加到最后

     $ cat file
     a11.t
     some text here
     a06.t
     some text here
     a11.t a54.g
    
     $ perl -pe '@nums=(/a(\d+)/g); s/$/ @nums/' file
     a11.t 11
     some text here 
     a06.t 06
     some text here 
     a11.t a54.g 11 54
    
    Run Code Online (Sandbox Code Playgroud)


Sté*_*las 10

sed这是完成任务的完美工具。但是请注意,您几乎不需要将多个sed调用通过管道连接在一起,因为sed脚本可以由多个命令组成。

如果您想提取 2 个十进制数字的第一个序列,并在找到后在行尾附加一个空格,您可以这样做:

sed 's/\([[:digit:]]\{2\}\).*$/& \1/' < your-file
Run Code Online (Sandbox Code Playgroud)

如果您只想在行上的第二个位置找到并遵循以下命令时才这样做a

sed 's/^a\([[:digit:]]\{2\}\).*$/& \1/' < your-file
Run Code Online (Sandbox Code Playgroud)

如果您不想这样做,如果该 2 位数字序列后跟更多数字:

sed 's/^a\([[:digit:]]\{2\}\)\([^[:digit:]].*\)\{0,1\}$/& \1/' < your-file
Run Code Online (Sandbox Code Playgroud)

稳健性而言,这一切都归结为回答这个问题:应该匹配什么?什么不应该?. 这就是为什么明确指定您的要求很重要,并了解输入可能是什么样子(比如在您不想找到匹配的行中是否有数字?输入中是否可以有非 ASCII 字符?输入是否以语言环境的字符集编码?等)。

以上,根据不同的sed实现中,输入将被解码成基于语言环境的字符映射文本(见的输出locale charmap),或者解释为,如果每个字节对应一个字符,0到127解释为按照ASCII字符映射字节(假设你”不在基于 EBCDIC 的系统上)。

对于sed第一类的实现,如果文件没有以正确的字符集编码,它可能无法正常工作。对于第二类,如果输入中存在编码包含十进制数字编码的字符,则可能会失败。