管道链中的功能

时间:2017-01-30 12:20:48

标签: linux bash shell sed

我有这个功能,输入参数是搜索字符串输入文件。功能适用于文件:

f_highlite() {
    sed -e 's/\($1\)/\o033[91m\1\o033[39m/g' $2
}

现在我想在管道中使用此功能。它应该如何修改?

ps aux | grep java | f_highlite "Xms" -

PS:我不确定如何确切地说出这个问题。如果你有更好的建议说出来。 ]

2 个答案:

答案 0 :(得分:3)

首先,您需要使用双引号,否则$1将无法展开:

f_highlite() {
    sed -e "s/\($1\)/\o033[91m\1\o033[39m/g" "$2"
}

顺便说一下,您需要确保$1不会包含sed作为语法元素理解的字符。对于Xms来说没关系。

关于该主题,您可以将-作为第二个参数传递给函数,因为sed-理解为 stdin

ps aux | grep Java | f_highlite "Xms" -

(谢谢@chepner!)

答案 1 :(得分:0)

您可能想了解另外两种方法,因为并非所有命令都支持-技巧。

第一个是具有在流上工作的函数,而不是将文件作为输入。您可以通过删除最后的$ 2并更改调用函数的方式

来实现
f_highlite() {
    sed -e 's/\($1\)/\o033[91m\1\o033[39m/g'
}

f_highlite <"Xms"

这将重定向文件的内容并将其连接到函数的标准输入(因此也是sed的)。

另一种方法是保持您的功能不变(我正在重复对另一个答案中建议的引用进行更正),但是使用进程替换将其提供给文件。

f_highlite() {
    sed -e "s/\($1\)/\o033[91m\1\o033[39m/g" "$2"
}

f_highlite < <(<"Xms")

这(至少从概念上讲)创建一个FIFO,其输入由文件内容提供,其输出连接到函数的输入。这里的关键是<(<"Xms")成为文件名(您可以尝试打印其名称来验证)。