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

时间:2012-03-23 22:51:28

标签: bash grep diff

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

cat file | grep -E ^[0-9]+$ > file_grep
diff file file_grep

问题是,我想在没有file_grep

的情况下这样做

我试过了:

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

diff file "`cat file | grep -E ^[0-9]+$`"

以及其他一些组合:-)但我无法让它发挥作用。 当diff获得额外参数时,我总是会收到错误,该参数是grep过滤的文件内容。

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

echo `ls`

由于

5 个答案:

答案 0 :(得分:52)

如果你正在使用bash:

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

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

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

diff <(this_command) <(that_command)

答案 1 :(得分:40)

最简单的方法是:

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

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

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

cat `echo file`

相当于:

cat file

和此:

diff file "`cat file | grep -E ^[0-9]+$`"

等同于:

diff file "123
234
456"

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

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

但在您的情况下,由于diff-的支持,因此不需要它。

答案 2 :(得分:9)

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

其中-表示“从标准输入读取”。

答案 3 :(得分:6)

尝试流程替换:

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

来自bash手册页:

  

流程替换

     

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

答案 4 :(得分:4)

在bash中,语法为

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