从当前目录中的某个类型的所有文件中删除最后n行,递归

时间:2013-04-04 18:18:40

标签: bash

我有以下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之前移除一个换行符,这个换行符已经存在

之前

2 个答案:

答案 0 :(得分:1)

如果您有

,那么您的第一个代码段应该有用
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文件中删除最后两行,并且不需要重定向和临时文件,因为它会对文件进行编辑。它也适用于包含空格的文件名和路径。