bash 处理来自管道的输入的函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18593632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Function to process input from pipe
提问by Hedge
I'm trying to write a bash-function to return a specific line of piped output by its number. Currently the full command looks like this:
我正在尝试编写一个 bash 函数以通过其编号返回特定的管道输出行。目前完整的命令如下所示:
mdfind 'my_search_string' | sed "2q;d"
That would return the 2nd line of output from the mdfind-command.
这将返回 mdfind 命令的第二行输出。
I'm trying to turn sed "$1q;d"
into a function that gets assigned as an alias.
我试图sed "$1q;d"
变成一个被分配为别名的函数。
How can I process the piped input?
如何处理管道输入?
回答by konsolebox
To return the second line of output, do this:
要返回第二行输出,请执行以下操作:
... | sed -ne 2p
And to use it as a function:
并将其用作函数:
function print_2nd_line {
sed -ne 2p
}
mdfind 'my_search_string' | print_2nd_line
You could also choose shorter names like p2
at your option.
您也可以选择较短的名称,例如p2
您的选择。
The function can also be customized to be capable of printing second line from specified files like:
该功能还可以自定义为能够从指定文件打印第二行,例如:
function print_2nd_line {
sed -ne 2p -- "$@"
}
print_2nd_line file
... | print_2nd_line ## Still could be used like this.
By the way the more efficient version would be
顺便说一下,更有效的版本是
sed -ne '2{p;q}'
UPDATE
更新
As suggested by Charles Duffy, you could also use this format for POSIX compatibility. Actually it's also compatible with all shells based from the original System V sh.
正如 Charles Duffy 所建议的,您也可以使用这种格式来实现 POSIX 兼容性。实际上,它也与基于原始 System V sh 的所有 shell 兼容。
print_2nd_line() {
sed -ne '2{p;q}' -- "$@"
}
Also, if you want to pass a custom line number to your function, you could have:
此外,如果您想将自定义行号传递给您的函数,您可以:
print_2nd_line() {
N=; shift
sed -ne "${N}{p;q}" -- "$@"
}
Where you can run it as:
你可以在哪里运行它:
... | print_2nd_line 2 ## Still could be used like this.
Or
或者
print_2nd_line 2 file
回答by William Pursell
You just need to protect the variable name:
你只需要保护变量名:
To define a function named search:
定义一个名为 search 的函数:
search() { ... | sed -n "p;q"; }
but note that this is not portable sed
. It would be better to do
但请注意,这不是便携式的sed
。这样做会更好
search() { ... | sed -n "{p; q;}"; }
Indeed, the original sed is not just non-portable, but does not do what you want! It should always quit after processing line 1. If you have a sed
that behaves as you describe in the question statement, you might want to double check!
确实,原来的 sed 不仅不可移植,而且不能做您想做的事!它应该总是在处理第 1 行后退出。如果你的sed
行为与你在问题陈述中描述的一样,你可能需要仔细检查!
回答by rook
My awked bash alias:
我的 awked bash 别名:
alias second="awk 'FNR==2'"
alias second="awk 'FNR==2'"
cat file | second
cat file | second
or
或者
second file
second file
So, I don't understand properly, do you want to write a function which gets number of line to filter as parameter? And also you want to process piped input in it to filter out that line? Your piped input will be arguments for your function and you could get all of them by $@
.
所以,我不太明白,你想写一个函数来获取要过滤的行数作为参数吗?而且您还想处理其中的管道输入以过滤掉该行?您的管道输入将是您的函数的参数,您可以通过$@
.
I'm sorry, I understand what the OP wanted :)
As I got it, he wants processing std
input by shell function with parameters, i.e.
对不起,我明白 OP 想要什么:)
正如我所知道的,他希望std
通过带参数的 shell 函数处理输入,即
cmd | func args
cmd | func args
So the following works:
所以以下工作:
function sift { awk "FNR==$1" ;}
function sift { awk "FNR==$1" ;}
Example:
例子:
cat file | sift 2
cat file | sift 2
(See comment about awk
vs sed
)
(参见关于awk
vs 的评论sed
)
回答by Charles Duffy
As an exercise -- this version is in pure bash, not using any external tools at all:
作为练习——这个版本是纯 bash,根本不使用任何外部工具:
return_line() {
local lineno=
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
The pure-bash version will typically be faster with short input streams (or when picking an early line from a long stream), but slower with long ones.
纯 bash 版本对于短输入流(或从长流中选择早期行时)通常会更快,但对于长输入流会更慢。