4

我正在尝试编写一个命令来替换不在行首的文本:

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 文件的脚本,我一直在研究这个文件有一段时间了。

4

5 回答 5

3

这应该适用于多个字符:

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

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

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

也应该工作

于 2013-09-11T22:19:28.303 回答
2

这应该这样做:

echo -e 'a b b\nb b c' | sed 's%\(.\)b%\1x%g'
于 2013-09-11T21:45:20.290 回答
1

借用Scrutinizer 的想法,这里有一个更通用的方法来保护一条线的一部分。诀窍是我们采用(单行)模式空间并在“要保护的部分”之后插入换行符。然后,我们只对“换行符之后的内容”进行更改。最后,我们删除保护性换行符。

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

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

(同样的方法可以用来保护接近行尾的文本,尽管要困难得多。)

(注意:这效率不高,因为 sed 现在必须更改每一行,一次添加保护器,然后再次删除它。如果您真的只是想保护多个前导bs 您可以将它们全部转换为换行符,然后把它们转回去。这更意味着允许保护,例如,每行的第一个“单词”。)

于 2013-09-11T23:11:56.850 回答
0

你的系统上有 Perl 吗?在这种情况下,这将作为 sed 命令的直接替换:

perl -pe '($c,$_)=/(.)(.*)/s;s/b/x/g;$_=$c.$_'
于 2013-09-11T23:38:03.373 回答
0

这可能对您有用(GNU sed):

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

或者

sed -r ':a;s/^(..*)b/\1x/;ta' file
于 2013-09-12T06:08:34.170 回答