-->

我怎样才能用sed来代替版权/许可证头在我的源文件?(How can I use sed to re

2019-07-17 18:16发布

我需要与Apache许可证2.0标头取代在我所有的Java源文件的LGPL许可头,即这

/*
 * Copyright (c) 2012 Tyler Treat
 * 
 * This file is part of Project Foo.
 *
 * Project Foo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Project Foo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Project Foo.  If not, see <http://www.gnu.org/licenses/>.
 */

需要成为

/*
 * Copyright (c) 2012 Tyler Treat
 * 
 * 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.
 */

我想最简单的方法是使用SED做了查找和替换在此版权头的所有地方。 我有点Unix的新手,所以我在得到命令工作的问题,我需要它的方式 - 尤其是对付多行字符串。 基本上,像下面,除了代替的相应报头foobar

find . -name "*.java" -print | xargs sed -i 's/foo/bar/g'

我明白了一个行sed的作品在同一时间,也许有更好的解决方案完全?

Answer 1:

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.'

c命令改变行指定的文本的范围内。 范围由含有“FOO项目是免费软件”到包含“与FOO项目沿”行了行标识。 该-i选项sed表示GNU sed ; 因此,我假设你已经GNU findxargs过了,使用-print0-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 {} +
$

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/^@\*@/ */' {} +
$

这追寻的线条开始@*@和替换文本“ * ”(空白星级)。 还不如整洁,但你不会被经常做这一切,我相信。



Answer 2:

部分许可证更换使用GNU桑达

您可以使用GNU sed的一些正则表达式匹配的线和读表达解决这个问题。 下面是步骤。

使用文件来保存替换文本

首先,创建一个文件来保存您的许可证的更换部分:

cat << EOF > /tmp/license
 * 
 * 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.
 */
EOF

运行实际桑达调用

接下来,运行发现收集您的文件列表,并调用下面的sed脚本来进行更改:

find . -name '*.java' |
xargs sed -i'' '/Copyright.*Tyler Treat/,/\*\// {
                    /Copyright/n
                    /\*\//r /tmp/license
                    d
                }'

兼容性注意

该解决方案可能会或可能不会与sed的其他版本,但在本地测试,并与著名的GNU sed的4.2.1版本的工作。 如果它不与sed的随附OS X版的版本中运行,可以安装GNU sed中通过的MacPorts或相似。



Answer 3:

假设文件1包含您的原文和file2包含您的版权置换的评论:

awk 'f; /\*\//{system("cat file2");f=1}' file1

以上只是查找第一个结束注释行的原始文件,当它找到猫的替换文件和为原文件的剩余部分进行打印圈。



文章来源: How can I use sed to replace copyright/license headers in my source files?