2012-03-23 63 views
34

我有这个简单的任务麻烦的命令使用管道:作为参数的差异

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

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

我曾尝试:

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

and

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

和其他一些组合:-)但我无法让它工作。 当diff获得额外的参数时,我总是收到一个错误,这是由grep过滤的文件内容。

同样的事情也总是为我工作,当我(使用反引号转义)想echo命令输出从这样的脚本中:

echo `ls` 

感谢

回答

38

如果你正在使用bash:

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

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

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

diff <(this_command) <(that_command) 
35

最简单的方法是:

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的为-支持。

+0

感谢您的帮助:-) – rluks 2012-03-23 23:06:36

+0

@ Pan.student:不客气! – ruakh 2012-03-23 23:08:26

+0

我可以像这样把整个命令放在测试中吗? 'if [-z grep -E'^ [0-9] + $'file | diff文件 - ];然后 echo“matches” fi' – rluks 2012-03-23 23:11:50

3

在bash,语法是

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

尝试过程取代:

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

从bash的手册页:

进程替换

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

+0

也适用,谢谢 – rluks 2012-03-23 23:08:07

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

其中-是指 “从标准输入读取”。