代码之家  ›  专栏  ›  技术社区  ›  abhiarora

使用sed确保bash参数始终以%符号结尾

  •  -1
  • abhiarora  · 技术社区  · 6 年前

    我在写一个爱好 bash 脚本(在学习过程中 sed 命令)。我写了一个函数,它接受零或一个参数并调用 pactl 最后一个参数始终以 % 签字。pactl命令控制my的扬声器 ubuntu machine . 我可以用它来改变音量,甚至增加音量 100% . 例如,要将音量设置为150%,我使用:

    pactl set-sink-volume 0 150%
    

    我用参数编写的函数检查:

    function increase {
        if [ "$#" -eq 2 ]; then
            pactl set-sink-volume $@
        elif [ "$#" -eq 1 ]; then
            pactl set-sink-volume 0 $1%
        fi
    }
    

    现在,如果用户只传递一个参数,我想确保只有一个 % 在辩论的最后签字。所以,我只想用 塞德 并在数字末尾显式添加%符号。

    我试过以下组合,但它们不起作用:

    echo "150%" | sed -n 's/\([^%]*\)%?/\1/p'
    
    echo "150%" | sed -n 's/\([^%]*\)%/\1/p'
    
    echo "150%" | sed -n 's/\(\d+\)/\1/p'
    
    echo "150%" | sed -n 's/\(\d+\)%/\1/p'
    
    echo "150%" | sed -n 's/\(\d+\)%?/\1/p'
    

    我所说的“不工作”是指当我试图同时通过150%和150%(回声“150”和回声“150%”在不同的时间)时,它在某一时间没有给出正确的结果。

    3 回复  |  直到 6 年前
        1
  •  2
  •   oguz ismail FCulig    6 年前

    捕获数字部分,追加 % 在替换中。例如:

    sed -n 's/^\([0-9]\{1,\}\)%*/\1%/p'
    

    使用GNU sed,它可以缩短为:

    sed -En 's/^([0-9]+)%*/\1%/p'
    

    不过,我更喜欢bash的regex匹配机制而不是sed来验证和清理这样的参数。

        2
  •  3
  •   RavinderSingh13 Nikita Bakshi    6 年前

    如果我答对了你的问题,请你试着回答。

    echo "150%" | sed 's/\([^%]*\)%.*/\1/'
    

    它将输出为 150 . 现在如果我们和 echo "150" 具体如下:

    echo "150" | sed 's/\([^%]*\)%.*/\1/'
    

    输出将是静止的 一百五十

    或者如果你想 % 在输出使用中也是如此(在看到@oguz ismail的答案添加了这个之后):

    echo "150%" | sed 's/\([^%]*\)%.*/\1%/'
    

    echo "150" | sed 's/\([^%]*\)%.*/\1%/'
    

    解释 sed 命令: 以下是对 塞德 命令它只是为了解释。

    echo "150%" |      ##echoing 150% and using pipe(|) sending its standard output as input to sed command.
    sed '              ##Starting sed command from here.
    s                  ##Using s option for using substitution.
    /\([^%]*\)%.*      ##Using memory buffer capability by taking everything before 1st occurrence of % and save it into (...) escaping \( and \) to remove its special meaning. Then mentioning % and everything else.
    /\1/               ##Now mentioning \1  means substitute complete Line with only matched 1st memory buffer value.
    '
    


    awk 回答:如果你同意 锥子 回答:

    echo "150%" | awk 'BEGIN{FS=OFS="%"} {print $1,""}'
    
        3
  •  2
  •   Adam D.    6 年前

    您的答案的问题是您使用了'\d',sed没有提供regex扩展名不过,您可以使用Posix字符类,因此可以执行以下操作:

    echo "150%%" | sed -E 's/^([^[:digit:]]*)([[:digit:]]+)(.*$)/\2%/'

        4
  •  1
  •   Ed Morton    6 年前

    你得到了你想要的sed答案,但仅供参考,你不会真的用sed做这样的工作,只是一个空壳补贴:

    $ cat tst.sh
    #!/usr/bin/env bash
    
    function increase {
        if [ "$#" -eq 2 ]; then
            echo pactl set-sink-volume "$@"
        elif [ "$#" -eq 1 ]; then
            echo pactl set-sink-volume 0 "${1%\%}%"
        fi
    }
    
    increase "$@"
    
    $ ./tst.sh 3 4
    pactl set-sink-volume 3 4
    
    $ ./tst.sh 150
    pactl set-sink-volume 0 150%
    
    $ ./tst.sh 150%
    pactl set-sink-volume 0 150%
    
    推荐文章