bash 使用命令管道作为 diff 的参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9847479/
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
Use pipe of commands as argument for diff
提问by rluks
I am having trouble with this simple task:
我在完成这个简单的任务时遇到了麻烦:
cat file | grep -E ^[0-9]+$ > file_grep
diff file file_grep
Problem is, I want to do this without file_grep
问题是,我想在没有 file_grep
I have tried:
我试过了:
diff file `cat file | grep -E ^[0-9]+$`
and
和
diff file "`cat file | grep -E ^[0-9]+$`"
and a few other combinations :-) but I can't get it to work.
I always get an error, when the diff
gets extra argument which is content of file filtered by grep
.
和其他一些组合:-) 但我无法让它工作。我总是收到一个错误,当diff
获取额外的参数是由grep
.
Something similar always worked for me, when I wanted to echo
command outputs from within a script like this (using backtick escapes):
类似的东西总是对我有用,当我想echo
从这样的脚本中命令输出时(使用反引号转义):
echo `ls`
Thanks
谢谢
回答by Keith Thompson
If you're using bash:
如果您使用 bash:
diff file <(grep -E '^[0-9]+$' file)
The <(COMMAND)
sequence expands to the name of a pseudo-file (such as /dev/fd/63
) from which you can read the output of the command.
该<(COMMAND)
序列扩展为伪文件的名称(例如/dev/fd/63
),您可以从中读取命令的输出。
But for this particular case, ruakh's solution is simpler. It takes advantage of the fact that -
as an argument to diff
causes it to read its standard input. The <(COMMAND)
syntax becomes more useful when both arguments to diff
are command output, such as:
但是对于这种特殊情况,ruakh 的解决方案更简单。它利用了这样-
一个事实,即作为参数diff
使其读取其标准输入。的<(COMMAND)
语法变得更加有用当两个参数diff
是命令输出,如:
diff <(this_command) <(that_command)
回答by ruakh
The simplest approach is:
最简单的方法是:
grep -E '^[0-9]+$' file | diff file -
The hyphen -
as the filename is a specific notation that tells diff
"use standard input"; it's documented in the diff
man-page. (Most of the common utilities support the same notation.)
-
作为文件名的连字符是一个特定的符号,它告诉diff
“使用标准输入”;它记录在diff
手册页中。(大多数常用实用程序都支持相同的表示法。)
The reason that backticks don't work is that they capture the output of a command and pass it as an argument. For example, this:
反引号不起作用的原因是它们捕获命令的输出并将其作为参数传递。例如,这个:
cat `echo file`
is equivalent to this:
相当于:
cat file
and this:
和这个:
diff file "`cat file | grep -E ^[0-9]+$`"
is equivalent to something like this:
相当于这样的事情:
diff file "123
234
456"
That is, it actually tries to pass 123234345
(plus newlines) as a filename, rather than as the contentsof a file. Technically, you could achieve the latter by using Bash's "process substitution" feature that actually creates a sort of temporary file:
也就是说,它实际上尝试将123234345
(加上换行符)作为filename传递,而不是作为文件的内容传递。从技术上讲,您可以通过使用 Bash 的“进程替换”功能来实现后者,该功能实际上创建了一种临时文件:
diff file <(cat file | grep -E '^[0-9]+$')
but in your case it's not needed, because of diff
's support for -
.
但在你的情况下,它是没有必要的,因为,diff
的支持-
。
回答by ashbyp
grep -E '^[0-9]+$' file | diff - file
where -
means "read from standard input".
where-
表示“从标准输入读取”。
回答by chepner
Try process substitution:
尝试进程替换:
$ diff file <(grep -E "^[0-9]+$" file)
From the bash manpage:
从 bash 联机帮助页:
Process Substitution
Process substitution is supported on systems that support named pipes (FIFOs) or the /dev/fd method of naming open files. It takes the form of <(list) or >(list). The process list is run with its input or output connected to a FIFO or some file in /dev/fd. The name of this file is passed as an argument to the current command as the result of the expansion. If the >(list) form is used, writing to the file will provide input for list. If the <(list) form is used, the file passed as an argument should be read to obtain the output of list.
过程替换
支持命名管道 (FIFO) 或命名打开文件的 /dev/fd 方法的系统支持进程替换。它采用 <(list) 或 >(list) 的形式。进程列表运行时其输入或输出连接到 FIFO 或 /dev/fd 中的某个文件。该文件的名称作为扩展的结果作为参数传递给当前命令。如果使用 >(list) 形式,写入文件将为列表提供输入。如果使用 <(list) 形式,则应读取作为参数传递的文件以获得 list 的输出。
回答by mob
In bash, the syntax is
在 bash 中,语法是
diff file <(cat file | grep -E ^[0-9]+$)