我正在尝试使用for循环将许可证标头添加到项目目录中的所有标头文件和源文件中。这是行不通的,是否还有其他使用方法sed
?
我正在尝试使用for循环将许可证标头添加到项目目录中的所有标头文件和源文件中。这是行不通的,是否还有其他使用方法sed
?
Answers:
这或多或少只是对Daniel Serodio的回答的扩展评论。我开始写它作为评论,但很快就变得太大了。
为了使bash全局递归,需要shopt -s globstar
。您必须启用globstar,否则**
将不起作用。globstar shell选项已引入bash的版本4中。
为避免处理目录,例如my.cpp/
,请使用test [[ -f $f ]]
...当测试位于双方括号中时,变量不需要用双引号引起来。
您还可以使用来考虑是否存在不匹配文件的可能性shopt -s nullglob
,它允许不匹配文件的模式扩展为空字符串,而不是自身。
为了处理多个模式,你可以链中的glob模式:**/*.cpp **/*.h
,但也许preferrably,当外壳选项extglob是上通过shopt -s extglob
,你可以使用这样的结构,例如**/*.@(cpp|h)
避免了在文件系统中的多个通行证; 每个模式一次。
如果您想.files
被包括在内,请使用.*.cpp
等,或使用shopt -s dotglob
为了安全地处理正在传输的文件,请sponge
从包中使用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
[[
可以正常处理null $f
。
unset x; [ -f $x ] && echo exists
报告“存在”……(固定)
**/*.@(cpp|h)
用$( find . -name "*.h" -name "*.cpp")
谢谢@ 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的建议。
targln=2; findln=$(sed -rne $targln'{\|// Copyright|=;q}' "$f"); if ((findln==targln));then
...但是,当然,除了其他所有方面之外,首先要对其进行彻底测试... PS。在Unix和Linux上的课程中,将这样的额外内容张贴在您的原始问题中,而不是作为答案,是
grep
中添加-q
选项grep
。始终在前后加上双引号$f
。
你可以做到这一点ex
或者ed
如果你喜欢(你不应该这样做sed
,你的要求,sed
旨在编辑流,-i
是各种原因一个坏主意):
shopt -s globstar
for _file in **/*.@(cpp|h); do
ed -s "${_file}" << EOF
0a
/* This file is licensed under the foo license.
All copyright strictly enforced by the copyright monster. */
.
w
EOF
done
sed -i
个坏主意?
sed -i
会断开符号链接和硬链接,从而导致意外行为。充其量它是非直觉的,更糟的是它是有害的。
#!/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
Gerhard Gappmeier的博客-如何递归替换源文件的文件头
博客文章附有一个 tar.gz
文件,其中包含所需的文件。
它有一个 header.template
文件,您可以在其中编写自定义注释,它可以跨越多行。
它有一个 remove_header.awk
脚本,可以用新的标题替换现有的标题。
为了运行它:
find . -name "*.h" -exec ~/rh/replace_header.sh {} \;