我正在尝试使用 for 循环将许可证头添加到项目目录中的所有头文件和源文件。这不起作用,还有其他方法使用吗sed
?
答案1
shopt -s globstar
for f in **/*.cpp; do
cat header_file "$f" > "$f.new" && mv "$f.new" "$f"
done
笔记:
- 这假设您对目录树具有完全(读+写+执行)访问权限。
- 所有
.cpp
文件都将重新创建,归您所有并具有默认权限。硬链接(如果有)将被破坏。
答案2
这或多或少只是对丹尼尔·塞罗迪奥回答。我开始把它写成评论,但它很快就变得太大了......
要使 bash glob 递归,它需要shopt -s globstar
.必须启用 globstar,否则**
不起作用。 globstar shell 选项是在 bash 版本 4 中引入的。
为了避免处理诸如 之类的目录my.cpp/
,请使用 test [[ -f $f ]]
... 当测试位于双方括号中时,变量不需要用双引号引起来。
您还可以通过使用 来考虑没有匹配文件的可能性shopt -s nullglob
,这允许不匹配文件的模式扩展为空字符串,而不是它们本身。
要处理多个模式,您可以链接 glob 模式:**/*.cpp **/*.h
,但也许更好的是,当 shell 选项外部全局变量是在via shopt -s extglob
,您可以使用这样的构造,例如**/*.@(cpp|h)
避免多次遍历文件系统;每个图案一次。
如果您想.files
包含在内,请使用.*.cpp
etc,或使用shopt -s dotglob
要安全地处理修改正在通过管道传输的文件,请使用sponge
from 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
答案3
谢谢@fred、@maxmackie、@enzotib。
您能检查一下我遵循的程序吗?
#!/bin/sh
# script to copy the headers to all the source files and header files
for f in *.cpp; do
if (grep Copyright $f);then
echo "No need to copy the License Header to $f"
else
cat license.txt $f > $f.new
mv $f.new $f
echo "License Header copied to $f"
fi
done
否则许可证头将被复制多次。
请建议我一种模式来遍历项目目录和子目录中的所有标题和源代码。
我无法完全理解@fred 的建议。
答案4
#!/bin/bash
for i in `find . -name '*.[m|h]'` # or whatever other pattern...
do
echo $i
if ! grep -q Copyright $i
then
cat copyright.txt $i >$i.new && mv $i.new $i
fi
done
enter code here