find . -name "*.java" -print0 | xargs -0 \
sed -i -e '/Project Foo is free software/,/along with Project Foo/c\
* Licensed under the Apache License, Version 2.0 (the "License");\
* you may not use this file except in compliance with the License.\
* You may obtain a copy of the License at\
*\
* http://www.apache.org/licenses/LICENSE-2.0\
*\
* Unless required by applicable law or agreed to in writing, software\
* distributed under the License is distributed on an "AS IS" BASIS,\
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\
* See the License for the specific language governing permissions and\
* limitations under the License.'
The c
命令将行范围更改为指定文本。该范围由包含“Project Foo 是免费软件”的行到包含“与 Project Foo 一起”的行标识。
这-i
选项sed
表示 GNUsed
;因此,我假设你有 GNUfind
and xargs
也,并且用过-print0
and -0
以避免文件名中出现空格等问题。
为此,我可能会想把sed
脚本写入文件(sed.script
),然后可以与以下命令一起使用:
find . -name "*.java" -exec sed -i -f sed.script {} +
我认为这更简洁,但情人眼里出西施。
只有一个问题:星号的对齐方式有点偏差,是否需要使用某种空白字符来缩进它们?我尝试在替换字符串中添加空格,但这似乎没有效果。
呃……这是我可以不需要的那种刺激(你也是)。似乎“更改”数据行上的前导空白被删除sed
。好像是sed
而不是bash
;我得到了相同的结果ksh
并且还使用脚本文件代替-e
命令行上的选项。您无法在输出时编辑“更改”数据。
一个可行的技巧——但你可能不喜欢它:
$ cat sed.script
/Project Foo is free software/,/along with Project Foo/c\
* Licensed under the Apache License, Version 2.0 (the "License");\
* you may not use this file except in compliance with the License.\
* You may obtain a copy of the License at\
*\
* http://www.apache.org/licenses/LICENSE-2.0\
*\
* Unless required by applicable law or agreed to in writing, software\
* distributed under the License is distributed on an "AS IS" BASIS,\
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\
* See the License for the specific language governing permissions and\
* limitations under the License.
$ s2p -f sed.script > perl.script
$ find . -name "*.java" -exec perl -f perl.script -i.bak {} +
$
The s2p
程序是 Perl 发行版的标准部分,它将sed
脚本转换为 Perl 脚本,但它保留替换数据中的前导空格。我对此并不热衷,但我能想到的唯一选择是对每个文件进行两次遍历。替换数据可能是:
$ cat sed.script
/Project Foo is free software/,/along with Project Foo/c\
@*@ Licensed under the Apache License, Version 2.0 (the "License");\
@*@ you may not use this file except in compliance with the License.\
@*@ You may obtain a copy of the License at\
@*@\
@*@ http://www.apache.org/licenses/LICENSE-2.0\
@*@\
@*@ Unless required by applicable law or agreed to in writing, software\
@*@ distributed under the License is distributed on an "AS IS" BASIS,\
@*@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\
@*@ See the License for the specific language governing permissions and\
@*@ limitations under the License.
$
完成主要文本替换后,您将执行以下操作:
$ find . -name "*.java" -exec sed -i 's/^@\*@/ */' {} +
$
这会追踪开始的行@*@
并将该文本替换为 '*
'(空白星号)。虽然没有那么整洁,但我相信你不会经常这样做。