删除bash中的前导字符串


10

我有一个类似的字符串rev00000010,我只想要最后一个数字,在这种情况下为10。

我已经试过了:

TEST='rev00000010'
echo "$TEST" | sed '/^[[:alpha:]][0]*/d'
echo "$TEST" | sed '/^rev[0]*/d'

两者均不返回任何内容,尽管regex似乎是正确的(尝试使用regexr


Answers:


16

您传递的命令的sed意思是:如果一行与正则表达式匹配,请将其删除。那不是你想要的。

echo "$TEST" | sed 's/rev0*//'

这意味着:在每一行上,删除rev后跟任意数量的零。

另外,您不需要sed这么简单的事情。只需使用bash及其参数扩展即可

shopt -s extglob         # Turn on extended globbing.
echo "${TEST##rev*(0)}"  # Remove everything from the beginning up to `rev`
                         # followed by the maximal number of zeroes.

5

POSIXly:

test='rev00000010'
number=${test#"${test%%[1-9]*}"}

将删除最左边的非零数字左边的所有东西。

伯尼/通用:

number=`expr "x$test" : 'xrev0*\(.*\)'`

第一个将以点,十六进制,空格等分隔:test='rev 003A0.1056'将产生number="3A0.1056"。第二个将在任何空间中断,将产生相同的值:003A0.1056来自expr。

3

如果您已经有了变量TEST,则在删除所有字母的情况下进行打印

printf "%.0f\n" ${TEST//[a-z]/}

要么

printf "%g\n" ${TEST//[a-z]/}

请勿使用%decho-command,0因为带前导的数字被理解为octal


2

还有其他一些选项(尽管我也建议您使用@choroba建议的参数扩展):

  • 使用sedperl将最后两个字符以外的所有内容替换为最后两个字符。这将有效删除除最后两个以外的所有内容。

    $ sed -r 's/.*(..)/\1/' <<<$TEST
    10
    $ perl -pe 's/.*(..)/\1/' <<<$TEST
    10
    
  • awk的字段分隔符设置为2或更大的0,然后打印最后一个字段:

    $ awk -F"00+" '{print $NF}' <<<$TEST
    10
    
  • 仅提取最后两个字符:

    $ grep -oP '..$' <<<$TEST
    10
    $ perl -lne '/(..)$/; print $1' <<<$TEST
    10
    
  • 仅输出最后10个字节:

    $ cut -b 10- <<<$TEST
    10
    

请注意,以上所有用法<<<$var都是bash构造。要在其他shell中使用它,请更改为echo "$TEST" | command


1
对于可以避免某些问题的awk其他变体awk -F"[a-z]" '{print +$NF}'
Costas 2014年

0

要获取“最后一个数字”,请选择字符串末尾的任何数字序列,并将其转换为十进制数字:

使用Bash:

 [[ "$test" =~  ([1-9][0-9]*)$ ]] && echo "number: $((10#${BASH_REMATCH[1]}))"

使用grep:

echo "$test" | grep -Po "[1-9][0-9]*$"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.