【问题标题】:How do i print arguments in reverse order in shell script? [duplicate]如何在 shell 脚本中以相反的顺序打印参数? [复制]
【发布时间】:2018-04-17 19:41:24
【问题描述】:

我试图编写一个以相反顺序打印参数的脚本。 所以如果我输入 bash reverse.sh 一二三 我希望我的输出是三二一 我怎样才能做到这一点? 这是我尝试过的,显然没有用......

#!/bin/bash
i=0
a="$"
for word in $*; do
  echo $a$(($#-i))
  i=$((i+1))
done  

这是我得到的输出

$3
$2
$1

我以为这会按 3、2、1 的顺序打印参数,但事实并非如此。我该怎么做?任何帮助都感激不尽。谢谢。

【问题讨论】:

    标签: bash shell command-line-arguments


    【解决方案1】:

    让我们定义你的论点:

    $ set -- one two three
    

    现在,让我们以相反的顺序打印出来:

    $ for ((i=$#;i>=1;i--)); do echo "${!i}"; done
    three
    two
    one
    

    工作原理

    for ((i=$#;i>=1;i--)) 启动一个循环,其中i$# 倒数到1。对于i 的每个值,我们通过${!i} 打印相应的位置参数。构造${!i} 使用间接${!i} 不返回i 的值,而是返回名称为$i 的变量的值。

    作为脚本

    在多行脚本形式中,我们可以使用:

    $ cat reverse 
    #!/bin/bash
    for ((i=$#;i>=1;i--))
    do
       echo "${!i}"
    done
    

    举个例子:

    $ bash reverse One Two Three
    Three
    Two
    One
    

    替代方案:使用 tac

    另一种以相反顺序打印的方法是使用实​​用程序tac。考虑这个脚本:

    $ cat reverse2
    #!/bin/bash
    printf "%s\n" "$@" | tac
    

    这是一个例子:

    $ bash reverse2 Uno Dos Tres
    Tres
    Dos
    Uno
    

    printf "%s\n" "$@" 每行打印一个位置参数。 tac 以相反的顺序打印这些行。

    限制:tac 方法只有在参数本身不包含换行符时才能正常工作。

    【讨论】:

    • tac 替代方法无法处理本身包含换行符的参数。
    • @chepner tac 方法的要点。我更新了答案以说明该限制。
    • tac 在 MacOS 上丢失,可以使用 tail -r 作为替代品
    【解决方案2】:

    你需要 evalecho 即你需要评估扩展,而不是输出它:

    eval echo $a$(($#-i))
    

    请注意,通常不鼓励使用eval,因为如果未对输入字符串进行清理,这可能会导致安全隐患。检查John1024's 的答案,看看在没有eval 的情况下如何做到这一点。

    【讨论】:

    • 对于不需要的任务,请不要推荐eval
    • @chepner 对。如果不被接受,我会删除答案,添加注释。
    猜你喜欢
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 2021-10-13
    • 2023-03-28
    • 2019-06-25
    相关资源
    最近更新 更多