好像我无法找到这个问题的直接答案。 我感谢您的帮助。 我正在尝试在目录中查找具有特定名称的所有文件,读取文件的最后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的解决方案工作正常。
答案 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)