如果我理解正确,您想要:
- 查找前 10 行中没有版权声明的文件,以及
- 为这些文件添加版权声明。
此外,您还希望:
- 在前 10 行中查找带有版权声明的文件,以及
- 将他们的通知更新为您的标准文本。
在我看来,这两个任务可以归结为一组:
- 删除前 10 行中的任何现有版权声明,然后
- 在文件中插入新的版权声明。
如果我们可以安全地假设您在问题的评论中输入的示例文本的缩短版本是有效的,并且应该插入例如每个文件的第 2 行,那么以下内容应该满足第一组要求,如果您正在使用 GNU sed:
find . -type f -not -exec grep -q Copyright {} \; -exec sed -i'' '2i/* Copyright */' {} \;
如果您没有运行 GNU sed(即您使用的是 FreeBSD、OSX 或 Solaris 等),请告诉我们,因为 sed 脚本会有所不同。
这是如何工作的?
该find
命令正在获取以下选项:
-type f
告诉它只查看文件(而不是目录或设备)。
-not
反转以下选项。
-exec grep -q Copyright {} \;
将搜索限制为包含版权的任何内容(由 修改-not
)
-exec sed -i'' '2i/* Copyright */' {} \;
插入您的版权声明。
如果您希望您的版权声明包含将由 sed 脚本解释的特殊字符,此解决方案可能会遇到困难。但它回答了你的问题。:)
相反,如果我们想处理修改后的要求,即首先删除现有的版权声明,那么我们可以使用两个单行代码来完成:
首先,我们删除现有的版权声明。
find . -type f -exec sh -c 'head {} | grep -q Copyright' \; -exec sed -ne '10,$ta;/Copyright/d;:a;p' {} \;
这可能有点多余,除非您想递归地遍历子目录,find
默认情况下这样做。sed 脚本对前 10 行中没有版权信息的文件不执行任何操作,因此如果您的所有文件都在一个目录中,则以下内容也应该起作用:
for file in *;do sed -ne '10,$ta;/Copyright/d;:a;p' "$file"; done
接下来,我们重新添加新的。
for file in *;do sed -i'' '2i/* Copyright */' "$file"; done
或者,如果您想通过子目录递归地执行此操作:
find . -type f -exec sed -i'' '2i/* Copyright */' {} \;
最后更新:
在这之后我不能再花更多时间在这上面了。
find . -type f \
-exec sh -c 'head {} | grep -q Copyright' \; \
-exec sed -ne '1h;1!H;${;g;s:/\*.*Copyright.*\*/:/* Copyright 1998-2012 */' {} \;
什么?
第一个-exec
在文件的前 10 行中搜索“版权”一词。就像我在上面发布的第一个示例一样。如果 grep 找到任何东西,则此条件返回 true。
第二个-exec
是替换。它将整个文件读入 sed 的保持缓冲区。然后,当它到达文件末尾时,它 ( g
) 考虑保持缓冲区,并且 ( s
) 执行多行替换。
请注意,这很可能需要一些调整,如果您在文件的其他地方有注释,它可能根本不起作用。我不记得 GNU sed 是否支持非贪婪星。你可以自己研究一下。
这是我的测试:
$ printf 'one\n/* Copyright blah blah\n *\n */\ntwo\n' | sed -n '1h;1!H;${;g;s:/\*.*Copyright.*\*/:/* Copyright 1998-2012 */:g;p;}'
one
/* Copyright 1998-2012 */
two
这不会维护您现有的版权信息,但至少它解决了多行问题。