处理来自管道的输入的函数

时间:2013-09-03 13:29:51

标签: bash shell

我正在尝试编写一个bash函数来返回一个特定的管道输出行。 目前,完整命令如下所示:

mdfind 'my_search_string' | sed "2q;d"

这将返回mdfind-command的第二行输出。

我正在尝试将sed "$1q;d"转换为一个被指定为别名的函数。

如何处理管道输入?

4 个答案:

答案 0 :(得分:7)

要返回第二行输出,请执行以下操作:

... | sed -ne 2p

并将其用作功能:

function print_2nd_line {
    sed -ne 2p
}

mdfind 'my_search_string' | print_2nd_line

您也可以根据需要选择p2等较短的名称。

该功能也可以自定义,以便能够从指定的文件打印第二行,如:

function print_2nd_line {
    sed -ne 2p -- "$@"
}

print_2nd_line file
... | print_2nd_line  ## Still could be used like this.

顺便提一下,效率更高的版本

sed -ne '2{p;q}'

<强>更新

根据Charles Duffy的建议,您也可以将此格式用于POSIX兼容性。实际上它也与基于原始System V sh的所有外壳兼容。

print_2nd_line() {        
    sed -ne '2{p;q}' -- "$@"
}

此外,如果您想将自定义行号传递给您的函数,您可以:

print_2nd_line() {
    N=$1; shift
    sed -ne "${N}{p;q}" -- "$@"
}

您可以将其作为:

运行
... | print_2nd_line 2  ## Still could be used like this.

或者

print_2nd_line 2 file

答案 1 :(得分:2)

您只需要保护变量名称:

定义名为search的函数:

search() { ... | sed -n "${1}p;q"; }

但请注意,这不是可移植的sed

会更好
search() { ... | sed -n "${1}{p; q;}"; }

事实上,原来的sed不只是不便携,而是不能做你想要的!处理第1行后应始终退出。如果您的sed行为与问题陈述中描述的相同,则可能需要仔细检查!

答案 2 :(得分:0)

我的bash别名:

alias second="awk 'FNR==2'"

cat file | second

second file

所以,我不明白,你是否想要编写一个能够过滤行数作为参数的函数?您还想在其中处理管道输入以过滤掉该行吗?您的管道输入将是您的功能的参数,您可以通过$@获得所有这些参数。

对不起,我明白OP想要什么:) 当我得到它时,他希望通过带有参数的shell函数处理std输入,即

cmd | func args

以下是有效的:

function sift { awk "FNR==$1" ;}

示例:

cat file | sift 2

(请参阅有关awk vs sed)的评论

答案 3 :(得分:0)

作为练习 - 这个版本是纯粹的bash,根本不使用任何外部工具:

return_line() {
  local lineno=$1
  while (( lineno > 1 )); do read; (( lineno-- )); done
  read -r && printf '%s\n' "$REPLY"
}

# ...to test...
return_line 3 <<<$'one\ntwo\nthree\nfour'

# ...and yes, this works with pipelines...
printf 'one\ntwo\nthree\nfour' | return_line 3

对于短输入流(或从长流中选择早期行),纯bash版本通常会更快,但对于长流则更慢。