Tyl*_*eat 8 unix macos command-line licensing sed
我需要使用Apache License 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/>.
*/
Run Code Online (Sandbox Code Playgroud)
需要成为
/*
* 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.
*/
Run Code Online (Sandbox Code Playgroud)
我认为最简单的方法是使用sed对所有出现的版权标题进行查找和替换.我是一个Unix新手,所以我遇到问题,让命令按照我需要的方式工作 - 特别是处理多行字符串.基本上,如下所示,除了相应的标题代替foo和bar:
find . -name "*.java" -print | xargs sed -i 's/foo/bar/g'
Run Code Online (Sandbox Code Playgroud)
我知道sed一次只能在一行上工作,所以也许总有一个更好的解决方案?
Jon*_*ler 12
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.'
Run Code Online (Sandbox Code Playgroud)
该c命令将行的范围更改为指定的文本.该范围由包含'Project Foo is free software'的行标识,直到包含'with Project Foo'的行.表示GNU 的-i选项; 因此,我假设你已经GNU 和过了,使用和避免的问题,在文件名等空白sedsedfindxargs-print0-0
为此,我可能想把sed脚本放到一个文件(sed.script)中,然后可以用于:
find . -name "*.java" -exec sed -i -f sed.script {} +
Run Code Online (Sandbox Code Playgroud)
我认为这更整洁,但美观是旁观者的眼睛.
只有一个问题:星号上的对齐方式有点偏差,是否需要使用某种空白字符来缩进它们?我尝试在替换字符串中添加空格,但似乎没有效果.
Grrr ......那是我无法做到的那种烦恼(你也是).似乎"变更"数据线上的前导空白被忽略了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 {} +
$
Run Code Online (Sandbox Code Playgroud)
该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.
$
Run Code Online (Sandbox Code Playgroud)
在完成主文本替换后,您将执行以下操作:
$ find . -name "*.java" -exec sed -i 's/^@\*@/ */' {} +
$
Run Code Online (Sandbox Code Playgroud)
这将跟踪行开始@*@并用' *'(空白星号)替换该文本.不是那么干净整洁,但我不会经常这样做,我相信.
您可以使用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
Run Code Online (Sandbox Code Playgroud)
接下来,运行find来收集文件列表,并调用以下sed脚本进行更改:
find . -name '*.java' |
xargs sed -i'' '/Copyright.*Tyler Treat/,/\*\// {
/Copyright/n
/\*\//r /tmp/license
d
}'
Run Code Online (Sandbox Code Playgroud)
此解决方案可能适用于或不适用于其他版本的sed,但已在本地进行测试,并且已知可与GNU sed版本4.2.1一起使用.如果它不适用于您的OS X版本附带的sed版本,则可以通过MacPorts或类似方式安装GNU sed .