将两个文件重定向到标准输入
有几个 UNIX 命令被设计用于操作两个文件。通常,此类命令允许通过使用单个破折号代替文件名来从标准输入读取其中一个“文件”的内容。
我刚刚遇到一种技术,它似乎允许从标准输入读取这两个文件:
comm -12 <(sort file1) <(sort file2)
我最初的难以置信的反应是,“这不应该起作用。标准输入只会将两个文件连接起来。该命令将无法区分这些文件,甚至无法意识到它已被赋予了两个文件的内容。”
当然,这种构造确实有效。我已经在 cygwin 1.7.7 上使用 bash 3.2.51 使用 comm
和 diff
对其进行了测试。我很好奇它是如何以及为什么起作用的:
- 为什么会起作用?
- 这是 Bash 扩展,还是直接的 Bourne shell 功能?
- 这适用于我的系统,但此技术也适用于其他平台吗? (换句话说,使用这种技术编写的脚本可以移植吗?)
There are several unix commands that are designed to operate on two files. Commonly such commands allow the contents for one of the "files" to be read from standard input by using a single dash in place of the file name.
I just came across a technique that seems to allow both files to be read from standard input:
comm -12 <(sort file1) <(sort file2)
My initial disbelieving reaction was, "That shouldn't work. Standard input will just have the concatenation of both files. The command won't be able to tell the files apart or even realize that it has been given the contents of two files."
Of course, this construction does work. I've tested it with both comm
and diff
using bash 3.2.51 on cygwin 1.7.7. I'm curious how and why it works:
- Why does this work?
- Is this a Bash extension, or is this straight Bourne shell functionality?
- This works on my system, but will this technique work on other platforms? (In other words, will scripts written using this technique be portable?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Bash、Korn shell(至少是 ksh93)和 Z shell 都支持进程替换。这些对于实用程序来说显示为文件。试试这个:
您将看到与所示类似的文件描述符。
Bash, Korn shell (ksh93, anyway) and Z shell all support process substitution. These appear as files to the utility. Try this:
You'll see file descriptors similar to the ones shown.
这是一个标准的 Bash 扩展。
<(sort file1)
使用sort file1
命令的输出打开一个管道,为该管道提供一个临时文件名,并将该临时文件名传递到>comm
命令行。您可以通过让
echo
告诉您正在传递给程序的内容来了解它的工作原理:This is a standard Bash extension.
<(sort file1)
opens a pipe with the output of thesort file1
command, gives the pipe a temporary file name, and passes that temporary file name on thecomm
command line.You can see how it works by getting
echo
to tell you what's being passed to the program: