bash 管道“查找”到“尾巴”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20936209/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Piping `find` to 'tail`
提问by Hari K
I want to get the last two lines of the find output and copy them somewhere. I tried
我想获取 find 输出的最后两行并将它们复制到某处。我试过
find . -iname "*FooBar*" | tail -2 -exec cp "{}" dest \;
but the output was "invalid option --2" for tail.
但是尾部的输出是“无效选项--2”。
Also, my file or directory name contains spaces.
此外,我的文件或目录名称包含空格。
采纳答案by l0b0
The following should work on absolutely any paths.
以下应该适用于绝对任何路径。
Declare a function to be able to use head
and tail
on NUL-separated output:
声明一个能够在 NUL 分隔的输出上使用head
和tail
的函数:
nul_terminated() {
tr 'find . -exec printf '%sfind . -iname "*FooBar*" -exec printf '%scp $(find . -iname "*FooBar*" | tail -2 ) dest
' {} \; | nul_terminated tail -n 2 | xargs -I "{}" -0 cp "{}" "dest"
' {} \; | nul_terminated tail -n 2
\n' '\nfind . -iname "*FooBar*"|tail -n2|xargs -i cp "{}" dest
' | "$@" | tr 'find . -iname "*FooBar*" | tail -n2 | while read file
do
cp "$file" "$dest"
done
\n' '\nwhile IFS=\n read file
'
}
Then you can use it to get a NUL-separated list of paths from your search after passing through tail
:
然后,您可以使用它在通过后从您的搜索中获取以 NUL 分隔的路径列表tail
:
while read line
do
cp "$line" dest;
done < $(find . -iname "*FooBar*" | tail -2)
You can then pipe that to xargs
and add your options:
然后,您可以将其通过管道传输到xargs
并添加您的选项:
Explanation:
解释:
find
files in the current directory (.
) and below with a name containingfoobar
(case insensitive because of thei
in-iname
);- for each file, run (
-exec
) a command to - print each file path (
{}
) followed by a NUL character (\0
) individually (\;
); - swap newlines and NUL characters (
tr '\0\n' '\n\0'
);" - get the last two lines (that is, paths;
tail -n 2
,"$@"
); - swap newlines and NUL characters again to get a NUL-separated list of file names (
tr '\0\n' '\n\0'
).
find
当前目录 (.
) 及以下目录中的文件,其名称包含foobar
(由于i
in 不区分大小写-iname
);- 对于每个文件,运行 (
-exec
) 一个命令 - 单独打印每个文件路径 (
{}
) 后跟一个 NUL 字符 (\0
) (\;
); - 交换换行符和 NUL 字符 (
tr '\0\n' '\n\0'
);" - 获取最后两行(即路径;
tail -n 2
,"$@"
); - 再次交换换行符和 NUL 字符以获取以 NUL 分隔的文件名列表 (
tr '\0\n' '\n\0'
)。
The xargs
command is a bit harder to explain. It builds as many cp ... "dest"
commands as necessary to fit in the maximum command lengthof the operating system, replacing the {}
token in the command with the actual file name (-I "{}" ... "{}"
), using the NUL character as a separator when reading the parameters (-0
).
该xargs
命令有点难以解释。它构建尽可能多的cp ... "dest"
命令以适应操作系统的最大命令长度,用{}
实际文件名 ( -I "{}" ... "{}"
)替换命令中的标记,在读取参数 ( -0
)时使用 NUL 字符作为分隔符。
回答by gturri
You can try
你可以试试
##代码##回答by Robin Green
Unfortunately this won't work with filenames that contain spaces or newlines.
不幸的是,这不适用于包含空格或换行符的文件名。
回答by David W.
Robin Green:
罗宾·格林:
$ find . -iname "*FooBar*"|tail -n2|xargs -i cp "{}" dest
Unfortunately this won't work with filenames that contain spaces or newlines.
$ find . -iname "*FooBar*"|tail -n2|xargs -i cp "{}" dest
不幸的是,这不适用于包含空格或换行符的文件名。
This will work (at least to the tail
) if the file contains spaces. That's because the find will put each file on one line including spaces, tabs, and other special characters.
tail
如果文件包含空格,这将起作用(至少对)。这是因为查找会将每个文件放在一行上,包括空格、制表符和其他特殊字符。
The problem is that xargs
will not operate with spaces. You can use the -0
or --null
option with xargs
, but that was designed with find ... -print0
in mind.
问题是xargs
不能用空格操作。您可以将-0
or--null
选项与 一起使用xargs
,但这是在设计时find ... -print0
考虑到的。
What might work is using a while
loop.
可能有效的是使用while
循环。
Since you're only reading in one item per line, the $file
will contain the file name with all of the various characters. The only time this will not work is if $file
contains a NL. Then, the tail
command itself will have issues. Fortunately, having a NL in a file name is quite rare.
由于您每行只读取一个项目,因此$file
将包含带有所有不同字符的文件名。唯一不起作用的是如果$file
包含 NL。然后,tail
命令本身就会有问题。幸运的是,文件名中包含 NL 是非常罕见的。
Some people do this:
有些人这样做:
##代码##which removes input separators on anything other than a NL, but that shouldn't be necessary.
这会删除 NL 以外的任何内容的输入分隔符,但这不是必需的。
回答by Ashish
Since You file contains 2 lines also have spaces lets keep inverted commas
由于您的文件包含 2 行也有空格让我们保留引号
##代码##