在 Bash 中动态构建命令管道

Kai*_*ina 5 variables bash command

我正在编写一个带有选项的 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
Run Code Online (Sandbox Code Playgroud)

如果-a选项,我打印整个文件,或者,如果-a选项和-s选项,我使用相同的命令,但我使用sort.

通过这个解决方案,如果我想实现-l,它将创建很多“if”语句。

我首先想到创建一个包含我的命令的变量。

例子:

sort='sort'
limit='grep -m3'
Run Code Online (Sandbox Code Playgroud)

然后这样写我的命令:

printf '%s\n' "${haikus[@]}" | sed -e 's/^[ \t]*//' | $sort | $limit
Run Code Online (Sandbox Code Playgroud)

但这根本行不通。

事实上,我想编写一个基本命令,并且能够根据选项添加更多命令。

如果没有大量的“if”语句,我怎样才能正确地做到这一点?

Joh*_*ica 3

这是一个很好的问题,但有一个棘手的、不那么明显的解决方案。

您可以做的是将几个函数调用链接在一起。这些函数可以检查相关标志,然后“执行某些操作”(例如 call )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
}
Run Code Online (Sandbox Code Playgroud)

要使用它们,您需要编写:

printf '%s\n' "${haikus[@]}" | sed -e 's/^[ \t]*//' | maybe_sort | maybe_limit
Run Code Online (Sandbox Code Playgroud)