Use pipe of commands as argument for diff

孤街浪徒 提交于 2019-12-03 01:52:15

问题


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

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.

Something similar always worked for me, when I wanted to echo command outputs from within a script like this (using backtick escapes):

echo `ls`

Thanks


回答1:


If you're using 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.

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:

diff <(this_command) <(that_command)



回答2:


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.)

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 contents of a file. Technically, you could achieve the latter by using Bash's "process substitution" feature that actually creates a sort of temporary file:

diff file <(cat file | grep -E '^[0-9]+$')

but in your case it's not needed, because of diff's support for -.




回答3:


grep -E '^[0-9]+$' file | diff - file

where - means "read from standard input".




回答4:


Try process substitution:

$ diff file <(grep -E "^[0-9]+$" file)

From the bash manpage:

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.




回答5:


In bash, the syntax is

diff file <(cat file | grep -E ^[0-9]+$)


来源:https://stackoverflow.com/questions/9847479/use-pipe-of-commands-as-argument-for-diff

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!