perl -pe one liner:用相同数量的不同字符替换所有匹配的字符。不全球化

时间:2016-03-19 10:29:23

标签: perl regex sed

我想知道是否有一个Perl(或其他)单行代码将用相同数量的抑扬符-替换所有连字符^,如果连字符从行的开头开始。

示例输入:

Title 1
-------
Title two
---------
   +--------+
   |asciibox|
   +--------+

输出应为:

Title 1
^^^^^^^
Title two
^^^^^^^^^
   +--------+
   |asciibox|
   +--------+

在Perl本身,我可以运行这样的东西:

s!(-+)!"^" x length($1)!e;

但有没有办法从命令行执行此操作?

3 个答案:

答案 0 :(得分:5)

是的,\G锚点与字符串的开头或上一场比赛后的位置匹配:

perl -pe 's/\G-/^/g'

您可以使用Perl或sed的另一种方式:测试和翻译

perl -pe 'y/-/^/ if /^-+$/'

sed '/^--*$/y/-/^/'

答案 1 :(得分:1)

您似乎拥有问题中的所有要素。您的主题行要求perl -pe并且您已经写了一个有效的替换,所以您只需要将两者结合起来

我不确定你的\b是什么意思;你需要^来锚定一行的开头。如果其他人正在阅读您的代码,那么最好坚持使用通常的斜杠分隔符。但您需要做的就是将替换用这样的引号括起来

perl -pe 's/^(-+)/"^" x length($1)/e' myfile.txt

输出

Title 1
^^^^^^^
Title two
^^^^^^^^^
   +--------+
   |asciibox|
   +--------+

答案 2 :(得分:0)

或多或少的有趣,两个(更多)解决方案避免/e

perl -pe '1 while s/^-*\K-/^/'

用插入符号重复替换从行开头开始的一系列短划线中的最后一个。在perl 5.10之前,可以使用1 while s/^(-*)-/$1^/代替。

perl -pe '$_=reverse; s/-(?=-*$)/^/g; $_=reverse'

首先,将线从前到后反转。然后,用插入符号重复替换任何除了它和行尾之间的其他破折号之外的任何破折号。最后,按正确的顺序放回线路。这两个reverse允许单个替换,因为s///g从左到右操作,允许可变长度前瞻,但镜像语句不正确。