在目录中查找文件,使用execdir执行命令并重定向

时间:2013-06-21 20:39:36

标签: linux redirect find

好像我无法找到这个问题的直接答案。 我感谢您的帮助。 我正在尝试在目录中查找具有特定名称的所有文件,读取文件的最后1000行并将其复制到同一目录中的新文件中。举个例子:

在当前目录中查找所有文件名xyz.log,将最后1000行复制到文件abc.log(不存在)。

我尝试使用以下命令但没有运气:

找到。 -name“xyz.log”-execdir tail -1000 {}> abc.log \;

我遇到的问题是,对于当前目录中的所有文件,它们都写入CURRENT目录中的abc.log而不是xyz.log所在的目录。显然,首先执行带有execdir的查找,然后将输出重定向到abc.log。

你们可以建议一种解决方法吗?我感谢任何信息/帮助。

编辑 - 我试过找。 -name“xyz.log”-execdir sh -c“tail -1000 {}> abc.log”\;正如一些朋友所建议的,但它给了我这个错误:“sh:./ tail:没有这样的文件或目录”错误信息。你们知道问题是什么吗?

幸运的是,使用-printf的解决方案工作正常。

3 个答案:

答案 0 :(得分:3)

最简单的方法是:

find . -name "xyz.log" -execdir sh -c 'tail -1000 "{}" >abc.log' \;

更灵活的选择是首先打印出命令,然后使用sh执行所有命令:

find . -name "xyz.log" -printf 'tail -1000 "%p" >"%h/abc.log"\n' | sh

您可以在尝试/调试时从结尾删除| sh

在某些版本的findutils中存在bug(4.2和4.3,虽然它已在某些4.2.x和4.3.x版本中修复),导致包含{}的execdir参数作为前缀使用./(而不是仅将前缀应用于{},它将应用于整个带引号的字符串)。要解决此问题,您可以使用:

find . -name "xyz.log" -execdir sh -c 'tail -1000 "$1" >abc.log' sh {} \;

sh -c 'script' arg0 arg1运行sh script,传递给arg0,arg1等。按照惯例,arg0是可执行文件的名称(此处为“sh”)。从脚本中,您可以使用$0(对应于“sh”),$1(对应于查找{}的扩展)等来访问参数。

答案 1 :(得分:0)

重定向未传递到execdir,因此abc.log显示在您运行命令的目录中。-execdir也不喜欢嵌入式重定向。但是你可以通过-execdir传递一个嵌入了重定向的shell命令来解决这个问题,如下所示:

find . -name "xyz.log" -execdir sh -c '/usr/bin/tail -1000 {} > abc.log' \;

这篇博文(不是我的)非常有用:

http://www.microhowto.info/howto/act_on_all_files_in_a_directory_tree_using_find.html

修改

我在命令中将完整路径设置为tail(假设它位于系统上的/ usr / bin中),因为sh可能会加载一个.profile,其PATH与当前shell不同。

答案 2 :(得分:0)

这是另一个非find(好吧,sorta - 它仍然使用find但是并没有试图将find用来做整件事:

while read f
do
  d=$(dirname "${f}")
  tail -n 1000 "${f}" > "${d}/abc.log"
done < <(find . -type f -name xyz.log -print)