如何将bash函数的参数扩展为管道命令链? [英] How can I expand arguments to a bash function into a chain of piped commands?
问题描述
我经常发现自己在做这样的事情很多:
I often find myself doing something like this a lot:
something | grep cat | grep bat | grep rat
当我回想起那三个单词肯定发生在某个地方, something
...的输出...现在,我可以这样做:
when all I recall is that those three words must have occurred somewhere, in some order, in the output of something
...Now, i could do something like this:
something | grep '.*cat.*bat.*rat.*'
但这意味着排序之后)。因此,我正在考虑在我的环境中添加一个名为 mgrep
的bash函数,该函数将转为:
but that implies ordering (bat appears after cat). As such, I was thinking of adding a bash function to my environment called mgrep
which would turn:
mgrep cat bat rat
转换为
grep cat | grep bat | grep rat
但我不太确定该怎么做(或者是否有其他选择? )。一个想法是循环参数,如下所示:
but I'm not quite sure how to do it (or whether there is an alternative?). One idea would be to for loop over the parameters like so:
while (($#)); do
grep $1 some_thing > some_thing
shift
done
cat some_thing
其中some_thing可能一些fifo,比如在bash中>(cmd)
但我不确定。如何继续?
where some_thing is possibly some fifo like when one does >(cmd)
in bash but I'm not sure. How would one proceed?
推荐答案
我相信你一次只能生成一条管道的命令,通过在每一步重定向标准输入。但是,将您的管道生成为字符串并使用eval执行它会更简单,更简单:
I believe you could generate a pipeline one command at a time, by redirecting stdin at each step. But it's much simpler and cleaner to generate your pipeline as a string and execute it with eval, like this:
CMD="grep '$1' " # consume the first argument
shift
for arg in "$@" # Add the rest in a pipeline
do
CMD="$CMD | grep '$arg'"
done
eval $CMD
生成一个总是从标准输入中读取的greps管道,就像在你的模型中一样。请注意,它保护引用参数中的空格,以便它在写入时正常工作:
This will generate a pipeline of greps that always reads from standard input, as in your model. Note that it protects spaces in quoted arguments, so that it works correctly if you write:
mgrep 'the cat' 'the bat' 'the rat'
这篇关于如何将bash函数的参数扩展为管道命令链?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!