使用命令管道作为diff的参数

rlu*_*uks 42 bash diff grep

我在完成这个简单的任务时遇到了麻烦:

cat file | grep -E ^[0-9]+$ > file_grep
diff file file_grep
Run Code Online (Sandbox Code Playgroud)

问题是,我想没有这样做 file_grep

我试过了:

diff file `cat file | grep -E ^[0-9]+$`
Run Code Online (Sandbox Code Playgroud)

diff file "`cat file | grep -E ^[0-9]+$`"
Run Code Online (Sandbox Code Playgroud)

和其他一些组合:-)但我不能让它工作.我总是得到一个错误,当diff得到额外的参数,这是过滤的文件的内容grep.

当我想echo在这样的脚本中命令输出时(使用反引号转义),类似的东西总是对我有用:

echo `ls`
Run Code Online (Sandbox Code Playgroud)

谢谢

Kei*_*son 59

如果你正在使用bash:

diff file <(grep -E '^[0-9]+$') file
Run Code Online (Sandbox Code Playgroud)

<(COMMAND)序列扩展到伪文件(如名称/dev/fd/63),从中可以读出的命令的输出.

但对于这种特殊情况,ruakh的解决方案更简单.它利用了这样-一个事实:作为一个参数,diff使它读取它的标准输入.的<(COMMAND)语法变得更加有用当两个参数diff是命令输出,如:

diff <(this_command) <(that_command)
Run Code Online (Sandbox Code Playgroud)


rua*_*akh 41

最简单的方法是:

grep -E '^[0-9]+$' file | diff file -
Run Code Online (Sandbox Code Playgroud)

连字符-作为文件名是一个特定的符号,告诉diff"使用标准输入"; 它记录在diff手册页中.(大多数常用实用程序支持相同的表示法.)

反引号不起作用的原因是它们捕获命令的输出并将其作为参数传递.例如,这个:

cat `echo file`
Run Code Online (Sandbox Code Playgroud)

相当于:

cat file
Run Code Online (Sandbox Code Playgroud)

还有这个:

diff file "`cat file | grep -E ^[0-9]+$`"
Run Code Online (Sandbox Code Playgroud)

相当于这样的东西:

diff file "123
234
456"
Run Code Online (Sandbox Code Playgroud)

也就是说,它实际上尝试将123234345(加上换行符)作为文件名传递,而不是作为文件的内容传递.从技术上讲,你可以通过使用Bash的"进程替换"功能实现后者,该功能实际上创建了一种临时文件:

diff file <(cat file | grep -E '^[0-9]+$')
Run Code Online (Sandbox Code Playgroud)

但在你的情况下,由于对它的diff支持,它不需要-.


ash*_*byp 9

grep -E '^[0-9]+$' file | diff - file
Run Code Online (Sandbox Code Playgroud)

其中的-意思是"从标准输入读取".


che*_*ner 6

尝试流程替换:

$ diff file <(grep -E "^[0-9]+$" file)
Run Code Online (Sandbox Code Playgroud)

从bash手册页:

流程替代

支持命名管道(FIFO)的系统或命名打开文件的/ dev/fd方法支持进程替换.它采用<(list)或>(list)的形式.运行进程列表时,其输入或输出连接到FIFO或/ dev/fd中的某个文件.作为扩展的结果,此文件的名称作为参数传递给当前命令.如果使用>(列表)表单,则写入文件将为列表提供输入.如果使用<(list)表单,则应读取作为参数传递的文件以获取列表的输出.


mob*_*mob 5

在 bash 中,语法是

diff file <(cat file | grep -E ^[0-9]+$)
Run Code Online (Sandbox Code Playgroud)