1

我有以下 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 或 for/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 之前删除一个换行符,它之前已经存在

4

2 回答 2

1

如果您有

shopt -s globstar

启用。

全球星

如果设置,文件名扩展上下文中使用的模式 '**' 将匹配所有文件以及零个或多个目录和子目录。如果模式后跟“/”,则只有目录和子目录匹配。

http://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html

于 2013-04-04T18:22:15.373 回答
1
find -name '*.h' -exec sed -i 'N;$!P;$!D;$d' '{}' ';'

这将从所有 .h 文件中删除最后两行,并消除对重定向和临时文件的需要,因为它会就地编辑文件。它也适用于包含空格的文件名和路径。

于 2013-04-04T18:29:36.103 回答