我正在编写一个带有选项的bash程序。
例如:./my_program -l 3 -a -s
-l 3
将输出限制为三行-a
将选择我的所有文件-s
将对输出进行排序就目前而言,我可以一次使用两个选项:
if [ $all == 1 ]
then
if [ $sort == 1 ]
then
printf '%s\n' "${haikus[@]}" | sed -e 's/^[ \t]*//' | sort
else
printf '%s\n' "${haikus[@]}" | sed -e 's/^[ \t]*//'
fi
fi
如果使用-a
选项,则打印整个文件;如果使用-a
选项和-s
选项,则使用相同的命令,但是使用sort
。
使用这种解决方案,如果我想实现-l
,它将创建很多“ if”语句。
我首先想到创建一个包含命令的变量。
示例:
sort='sort'
limit='grep -m3'
然后以这种方式编写我的命令:
printf '%s\n' "${haikus[@]}" | sed -e 's/^[ \t]*//' | $sort | $limit
但这根本行不通。
事实是,我想编写一个基本命令,并能够根据选项添加更多命令。
在没有大量“ if”语句的情况下如何正确执行此操作?
答案 0 :(得分:2)
一个棘手的问题,不太明显的解决方案。
您可以做的是将几个函数调用链接在一起。这些功能可以检查相关标志,然后“执行某些操作”(如调用sort
)或“不执行任何操作”,然后仅调用cat
。在管道中进行简单的cat
调用本质上是无操作的:它将stdin不变地复制到stdout。
maybe_sort() {
if [[ $sort == 1 ]]; then
sort
else
cat
fi
}
maybe_limit() {
if [[ -n $limit ]]; then
head -n "$limit"
else
cat
fi
}
要使用这些内容,请输入:
printf '%s\n' "${haikus[@]}" | sed -e 's/^[ \t]*//' | maybe_sort | maybe_limit
答案 1 :(得分:2)
您可以直接通过管道传递到if
语句。不过,在某些地方,这将需要像cat
这样的无操作滤镜,因此在这方面效率稍低。
printf '%s\n' "${haikus[@]}" | sed -e 's/^[ \t]*//' |
if [ "$sort" = 1 ]; then sort; else cat; fi |
if [ "$l" -gt 0 ]; then grep -m"$l"; else cat; fi
if
语句本身就是命令,因此它具有自己的文件描述符集,这些文件描述符是随附命令继承的。 if
语句本身不使用这些描述符进行任何操作,因此sort
和cat
都可以查看未包装的数据第一名。
答案 2 :(得分:0)
好的,大家好。我迟到了。我不知道我可以将cat用作不操作对象,而这正是我寻求的解决方案。 因此,我仅使用“ cat” op初始化了所有选项。如果正确触发了该选项,则只需使用良好的操作来更新字符串。 然后,我只需要编写一条包含所有选项的操作行即可。
非常感谢您。
答案 3 :(得分:0)
我正在寻找没有固定顺序的解决方案。结束于:
# assemble pipeline from sequence of arguments
# each argument interpreted as command to evaluate (e.g. spaces interpreted)
pipe_all() {
if [[ $# -gt 0 ]]; then
local current=$1
shift
eval "$current" | pipe_all "$@"
else
cat
fi
}
filter_weapon() {
grep '/Weapon/'
}
filters=()
filters+=(sort)
filters+=(uniq)
filters+=(filter_weapon)
filters+=("head -n $1") # should be encoded as a single argument and be a valid command
pipe_all "${filters[@]}"