我有以下bash脚本。
for i in **/*.h; do head $i -n -2 > $i.tmp && mv $i.tmp $i -f; done
目的是遍历当前目录中的每个.h文件,并从该文件中删除最后两行。
但是,这仅适用于直接位于当前目录的子文件夹中的文件,但它不处理子文件夹子文件夹中的文件等等,因此./foo/foobar.h会被处理,但是./foo/bar/foobar.h或/ bar / foobar / .foobar.h没有。
因此我尝试过这种方式:
for i in 'find -name *.h'; do head $i -n -2 > $i.tmp && mv $i.tmp $i -f; done
这失败了,因为> $ i.tmp含糊不清
我的脚本应该如何处理,以便它处理目录中的所有头文件,无论它们嵌套在子文件夹中有多深?
编辑: 如果原始文件在eof之前没有直接换行,则上面的工作第一个脚本(以及答案中的sed替代)将添加一个,因此如果不需要eof之前的换行,则必须将其删除算账:
for i in **/*.h; do head $i -n -2 > $i.tmp && mv $i.tmp $i -f && truncate --size=-2 $i; done
对于CRLF(Windows风格)换行符,大小应为-2;对于CR(旧MacOS样式)和LF(unix样式),行结尾
,大小应为-1当然这种方法也会在eof之前移除一个换行符,这个换行符已经存在
之前答案 0 :(得分:1)
如果您有bash4和
,那么您的第一个代码段应该有用shopt -s globstar
启用。
globstar
如果设置,文件名扩展上下文中使用的模式“**”将匹配所有文件以及零个或多个目录和子目录。如果模式后跟'/',则只有目录和子目录匹配。
请参阅http://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html
答案 1 :(得分:1)
find -name '*.h' -exec sed -i 'N;$!P;$!D;$d' '{}' ';'
这将从所有.h文件中删除最后两行,并且不需要重定向和临时文件,因为它会对文件进行编辑。它也适用于包含空格的文件名和路径。