我正在尝试编写一个bash函数来返回一个特定的管道输出行。 目前,完整命令如下所示:
mdfind 'my_search_string' | sed "2q;d"
这将返回mdfind-command的第二行输出。
我正在尝试将sed "$1q;d"
转换为一个被指定为别名的函数。
如何处理管道输入?
答案 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版本通常会更快,但对于长流则更慢。