sed - 匹配不是行的开头

时间:2013-09-11 21:41:15

标签: regex bash sed awk

我正在尝试编写一个替换行开头的文本NOT的命令:

echo -e 'a b b\nb b c' | sed 's%^b%x%g'

输出:

a b b
x b c

期望的输出:

a x x
b x c

我正在编写一个解析400 MB文件的脚本,而且我一直在敲打这个文件。

5 个答案:

答案 0 :(得分:3)

这应该适用于多个字符:

sed 's/^b/\
/; s/b/x/g; s/^\n/b/' 

有些sed在替换部分接受\n,所以在这种情况下

sed 's/^b/\n/; s/b/x/g; s/^\n/b/'

也应该工作

答案 1 :(得分:2)

这应该这样做:

echo -e 'a b b\nb b c' | sed 's%\(.\)b%\1x%g'

答案 2 :(得分:1)

借用Scrutinizer's idea,这是保护部分线路的更通用的方法。诀窍是我们采用(单行)模式空间并在“要保护的部分”之后插入换行符。然后,我们仅对“换行后的内容”进行更改。最后,我们删除了保护换行符。

除了任何(一个或多个)“行首”b之外,此版本更改所有b,因此,例如,“bbc”变为“bxc”但是“bbc bbc” “变成”bbc bxc“而不是”bxc bxc“。

sed -e 's/^b*/&\
/
s/\n\(.*\)b/\1x/g
s/\n//'

(可以使用相同的方法保护文本到行尾,尽管这样做要困难得多。)

(注意:这不是那么有效,因为现在必须改变每一行,一次添加保护器然后再删除它。如果你真的只想保护多个前导b你可以将它们全部转换为换行符,然后将其转回。这更多的意思是允许保护,例如,每行上的第一个“单词”。)

答案 3 :(得分:0)

您的系统上是否有可用的Perl?在这种情况下,这将作为sed命令的直接替代:

perl -pe '($c,$_)=/(.)(.*)/s;s/b/x/g;$_=$c.$_'

答案 4 :(得分:0)

这可能适合你(GNU sed):

sed '/^b/s/b/x/2g;/^b/!s/b/x/g' file

sed -r ':a;s/^(..*)b/\1x/;ta' file