我想获取find输出的最后两行并将它们复制到某处。我试过了
find . -iname "*FooBar*" | tail -2 -exec cp "{}" dest \;
但输出是“无效选项--2”尾部。
此外,我的文件或目录名称包含空格。
答案 0 :(得分:5)
以下内容绝对可以用于任何路径。
声明一个能够use head
and tail
on NUL-separated output的函数:
nul_terminated() {
tr '\0\n' '\n\0' | "$@" | tr '\0\n' '\n\0'
}
然后,您可以使用它在通过tail
后从搜索中获取NUL分隔的路径列表:
find . -exec printf '%s\0' {} \; | nul_terminated tail -n 2
然后,您可以将其传送到xargs
并添加选项:
find . -iname "*FooBar*" -exec printf '%s\0' {} \; | nul_terminated tail -n 2 | xargs -I "{}" -0 cp "{}" "dest"
说明:
find
)及其下方的.
个文件,其名称包含foobar
(因i
中的-iname
而不区分大小写); -exec
)命令{}
),然后打印一个NUL字符(\0
); \;
);“tr '\0\n' '\n\0'
,tail -n 2
); "$@"
)。 tr '\0\n' '\n\0'
命令有点难以解释。它根据需要构建尽可能多的xargs
命令以适应操作系统的最大命令长度,将命令中的cp ... "dest"
标记替换为实际文件名({{ 1}}),在读取参数({}
)时使用NUL字符作为分隔符。
答案 1 :(得分:4)
你可以尝试
cp $(find . -iname "*FooBar*" | tail -2 ) dest
答案 2 :(得分:2)
find . -iname "*FooBar*"|tail -n2|xargs -i cp "{}" dest
不幸的是,这不适用于包含空格或换行符的文件名。
答案 3 :(得分:2)
$ find . -iname "*FooBar*"|tail -n2|xargs -i cp "{}" dest
Unfortunately this won't work with filenames that contain spaces or newlines.
如果文件包含空格,这将起作用(至少到tail
)。这是因为find会将每个文件放在一行上,包括空格,制表符和其他特殊字符。
问题是xargs
不能用空格操作。您可以将-0
或--null
选项与xargs
一起使用,但设计时考虑到find ... -print0
。
可能有效的方法是使用while
循环。
find . -iname "*FooBar*" | tail -n2 | while read file
do
cp "$file" "$dest"
done
由于您每行只读一个项目,$file
将包含包含所有各种字符的文件名。唯一不行的是$file
包含NL。然后,tail
命令本身会出现问题。幸运的是,在文件名中使用NL非常罕见。
有些人这样做:
while IFS=\n read file
删除NL以外的任何输入分隔符,但这不是必需的。
答案 4 :(得分:1)
由于你的文件包含2行也有空格让我们保留引号“
while read line
do
cp "$line" dest;
done < $(find . -iname "*FooBar*" | tail -2)
答案 5 :(得分:0)
我会做的:
find . -iname "filename" -exec tail -n 2 {} \; > output.txt