使用管道将两个参数传递给命令


20

通常,我们只需要传递一个参数:

echo abc | cat
echo abc | cat some_file -
echo abc | cat - some_file

有没有办法传递两个参数?就像是

{echo abc , echo xyz} | cat
cat `echo abc` `echo xyz`

我可以先将结果存储在一个文件中

echo abc > file1
echo xyz > file2
cat file1 file2

但后来我可能不小心覆盖了一个文件,这是不行的。这将进入非交互式脚本。基本上,我需要一种方法将两个任意命令的结果传递给 cat 无需写入文件。


更新: 对不起,该示例掩盖了问题。而 { echo abc ; echo xyz ; } | cat 似乎确实有效,输出是由于 echo s,而不是 cat

一个更好的例子是 { cut -f2 -d, file1; cut -f1 -d, file2; } | paste -d, 哪个不能按预期工作。

file1:
a,b
c,d

file2:
1,2
3,4

预期产出是:

b,1
d,3

解决:

使用 过程替代 cat <(command1) <(command2)

或者,使用命名管道 mkfifo

mkfifo temp1
mkfifo temp2
command1 > temp1 &
command2 > temp2 &
cat temp1 temp2

不太优雅,更冗长,但工作正常,只要你确保temp1和temp2不存在。


1
这让我抓狂了头。您想将两个不同的命令传递给一只猫吗?
user606723

2
你知道“管道”和“论据”是两个完全不相关的概念,对吧?
Ignacio Vazquez-Abrams

@Ignacio错误......我对Linux并不熟悉,所以我真的不知道它的区别。我一直认为管道意味着它将以前的结果作为一个参数。关心赐教?
goweon

@firebat no,pipe表示将前一个命令的stdout作为下一个命令的标准输入。您仍然可以拥有参数,这是一个不同的概念。
Rich Homolka

另外,就你的更新文本而言,输出确实来自cat,只是你希望语句看起来与cat分开,因为它们被序列化为一个流所以它无法做到。
Rich Homolka

Answers:


16

我想你想要'过程替代' http://tldp.org/LDP/abs/html/process-sub.html 。它也适用于zsh,虽然它有更多选项,语法可能不同。

它创建一个伪文件( /dev/fd/something )对于每次替换。这非常有用。该命令只能作为流读取,这意味着它不能与fseek来回转换。它需要将其作为字节流读取,就像管道一样。

您的示例用作进程替换:

cat <(echo abc) <(echo xyz)
paste -d, <(cut -f2 -d, file1) <(cut -f1 -d, file2)

可以把它想象成一个使用进程的工具,并假装它是一个没有任何临时文件的文件。

(从我的 早点回答


2

我喜欢xargs 作为一个例子,我想在/ usr / local下找到所有mysql数据目录的大小

osx:local user$ pwd
/usr/local
osx:local user$  ls | grep mysql 
mysql
mysql-5.0.51a-osx10.5-x86_64
mysql-5.0.51b-osx10.5-x86_64
mysql-5.1.39-osx10.5-x86_64
mysql-5.6.17-osx10.7-x86_64
os x:local user$  ls | grep mysql |sudo  xargs du -sh
4.0K    mysql
2.8G    mysql-5.0.51a-osx10.5-x86_64
 10G    mysql-5.0.51b-osx10.5-x86_64
 25G    mysql-5.1.39-osx10.5-x86_64
753M    mysql-5.6.17-osx10.7-x86_64
osx:local user$ 

xargs的


1

由于管道操作员将分组命令的标准输出连接到第三个命令的标准输入,因此花括号实际上有效。

您可以通过运行任何不使用标准输入的命令来判断打印输出是否来自回声,例如 { echo 1; echo 2;} | echo 3 将打印3而不是1 \ n2 \ n3。

但是,这不是您想要的,因为花括号中的两个命令正在写入相同的输出 cat - 他们的结果。生成两个不同的结果,用作命令的两个参数 paste,您将不得不使用临时文件或命名管道。

您可以使用 mktemp 生成一个唯一的临时文件或 mkfifo 创建FIFO管道文件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.