如何为目录中的所有 .h 和 .cpp 文件递归地添加许可证头

Sat*_*dra 21 shell-script text-processing

我正在尝试使用 for 循环向项目目录中的所有头文件和源文件添加许可证头。这不起作用,是否还有其他方法使用sed

Dan*_*dio 16

shopt -s globstar

for f in **/*.cpp; do
  cat header_file "$f" > "$f.new"  &&  mv "$f.new" "$f"
done
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 这假设您对目录树具有完全(读+写+执行)访问权限。
  • 所有.cpp文件都将重新创建,归您所有并具有默认权限。硬链接(如果有)将被破坏。


Pet*_*r.O 13

这或多或少只是对Daniel Serodio回答的扩展评论。我开始写它作为评论,但它很快变得太大了......

对于要递归的 bash glob,它需要shopt -s globstar. 您必须启用 globstar,否则**不起作用。bash 版本 4 中引入了 globstar shell 选项。

为避免处理诸如 之类的目录my.cpp/,请使用 test [[ -f $f ]]... 当测试在双方括号中时,变量不需要双引号。

您还可以通过 using 考虑没有匹配文件的可能性shopt -s nullglob,这允许不匹配文件的模式扩展为空字符串,而不是它们本身。

为了处理多个模式,你可以链中的glob模式:**/*.cpp **/*.h,但也许preferrably,当外壳选项extglob通过shopt -s extglob,你可以使用这样的结构,例如**/*.@(cpp|h)避免了在文件系统中的多个通行证; 每个图案一次。

如果您想.files被包括在内,请使用.*.cpp等,或使用shopt -s dotglob

要安全地修改正在通过管道传输的文件,请使用spongefrom package moreutils(它使您无需创建自己的临时文件)


printf "// The License\n\n" > /tmp/$USER-license

shopt -s globstar nullglob extglob
for f in **/*.@(cpp|h) ;do
  [[ -f $f ]] && cat "/tmp/$USER-license" "$f" | sponge "$f"
done
Run Code Online (Sandbox Code Playgroud)