替换多个文件中的一行,限制为行号范围

时间:2013-05-21 08:13:45

标签: bash sed

我有大量文件,我想从所有这些文件中替换一些行。我不知道这些行的确切内容,我所知道的都是包含两个已知的单词 - 比方说'Programmer'和'Bob'。所以我想要替换的行可能是:

Created by Programmer Bob
Programmer extraordinaire Bob, such an awesome guy
Copyright programmer bob, all rights reserved

到目前为止这听起来很容易,但问题是我只想替换行范围内包含的行 - 例如在文件的开头(通常会找到有关文件的注释)。我无法替换文件后面部分中找到的行,因为我不想意外地替换实际代码。

到目前为止,我已经尝试过:

find . -exec grep -il -E 'Programmer.*Bob' {} \; | xargs sed -i '1,10 /Programmer.*Bob/Ic\LINE REPLACED'

(我正在使用find因为grep遇到了无限递归 - 我想。这不是重点。)

然而,似乎我不能使用c \(更改行)的地址范围。随意指出任何语法错误,但我想我已经尝试了一切无济于事。没有行号,这确实有效。

编辑: 我得到了答案,但我决定编辑我的问题以包括我的解决方案,这扩展了我得到的答案 - 也许有人会觉得这很有帮助。

后来我意识到我想在行的开头保留可能的空格和注释字符。我使用这个命令完成了它:

find . -exec grep -ilI '.*Programmer.*Bob.*' {} \; xargs sed -i -r '1,10 s/([ \t#*]*)(.*Programmer.*Bob.*)/\1LINE REPLACED/I'

\ 1保持匹配[\ t#*] *的模式。可以将此更改为^ [\ t#*] *,将模式锚定到行的开头,但(我认为)此当前版本将更改

** Text I don't want to remove ** Programmer Bob

** Text I don't want to remove ** LINE REPLACED

实际上哪个更好。 (我还在find命令中添加了-I(大写i)标志,跳过了二进制文件。)

3 个答案:

答案 0 :(得分:0)

您正在混合地址和命令。简单替换应该有效:

find . -exec grep -il -E 'Programmer.*Bob' {} \; \
    | xargs sed -i '1,10 s/.*Programmer.*Bob.*/LINE REPLACED/'

答案 1 :(得分:0)

find . -type f -name "*.cpp"|xargs perl -pi -e 'if(/Programmer/ && /Bob/ && $.>=1 && $.<10){$_="line to replace"}'

答案 2 :(得分:0)

sed命令:

 >sed '1,10 {s/programmer\|bob/LINE REPLACED/i;s/programmer\|bob//ig}' file