提取数字子字符串并为其添加值

时间:2017-05-13 06:45:40

标签: bash shell

我有一个像1001.2001.3001.5001.60011001-2001-3001-5001-6001这样的字符串。如何提取第4个字符串,即5001,为其添加121之类的值,并将其放回同一个字符串中。输出应该类似于1001.2001.3001.5122.60011001-2001-3001-5122-6001。我必须在Linux bash脚本中实现这一点。

5 个答案:

答案 0 :(得分:1)

试试这个

#!/bin/bash
str=$1 
if [[ $(echo $str | grep '\.'  | wc -l) == 1 ]]
then
   str1=$(echo $str |  cut -d '.' -f 1,2,3)
   str2=$(echo $str | cut -d '.' -f 4 | awk {'print $1+121'})
   str3=$(echo $str |  cut -d '.' -f 5)
   echo $str1.$str2.$str3

elif [[ $(echo $str | grep - | wc -l) == 1 ]]
then
    str1=$(echo $str |  cut -d '-' -f 1,2,3)
    str2=$(echo $str | cut -d '-' -f 4 | awk {'print $1+121'})
    str3=$(echo $str |  cut -d '-' -f 5) 
    echo $str1-$str2-$str3
else
    echo "do nothing"
fi

传递一个字符串作为参数

答案 1 :(得分:1)

没有管道,没有叉子,没有切割,没有晃动,只是普通的POSIX外壳:

$ s=1001.2001.3001.5001.6001
$ oldIFS=$IFS
$ IFS=.-
$ set -- $s
$ case $s in
> (*.*) echo "$1.$2.$3.$(($4 + 121)).$5";;
> (*-*) echo "$1-$2-$3-$(($4 + 121))-$5";;
> esac
1001.2001.3001.5122.6001
$ IFS=$oldIFS

答案 2 :(得分:0)

一个班轮

value=121 ; str='1001.2001.3001.5001.6001' ; token="$(echo "$str" | cut -f 4 -d '.')" ; newtoken=$(( $token + $value )) ; newstr="$(echo "$str" | sed -e "s/$token/$newtoken/g" | tr '.' '-')" ; echo "$newstr"

故障:

value=121                                            # <- Increment
str='1001.2001.3001.5001.6001'                       # <- Initial String
token="$(echo "$str" | cut -f 4 -d '.')"             # <- Extract the 4th field with . sep
newtoken=$(( $token + $value ))                      # <- Add value and save to $newtoken
newstr="$(echo "$str" \
| sed -e "s/$token/$newtoken/g" \
| tr '.' '-')"                                       # <- Replace 4th field with $newtoken
                                                     #    and translate "." to "-"
echo "$newstr"                                       # <- Echo new string

适用于:

  • SH
  • FreeBSD的
  • Busybox的

使用开箱即用的工具

答案 3 :(得分:-1)

如果字段分隔符可以是.-,那么请执行类似

的操作
echo "1001.2001.3001.5001.6001" | awk 'BEGIN{FS="[.-]";OFS="-"}{$4+=121}1'
1001-2001-3001-5122-6001

但是,如果您需要将正则表达式FS或字段分隔符与OFS匹配,则需要安装gawk

echo "1001.2001.3001.5001.6001" |
gawk 'BEGIN{FS="[.-]"}{split($0,a,FS,seps)}{$4+=121;OFS=seps[1]}1'
1001.2001.3001.5122.6001

答案 4 :(得分:-1)

尽管使用值重置参数列表可能是首选方法,或者将IFS设置为分隔符并将值读入数组并将所需值添加到数组中有争议的索引,您也可以通过一个简单的循环来查找分隔符并不断跳过字符,直到找到所需的段(在您的情况下为4 - 当分隔符计数时是3)。然后只需在每个数组索引处附加数字,直到找到下一个分隔符,它将为您提供基值。只需将所需的121添加到已完成的号码即可完成脚本,例如

#!/bin/bash

str=${1:-"1001.2001.3001.5001.6001"}    ## string
ele=${2:-4}     ## element to add value to [1, 2, 3, ...]
add=${3:-121}   ## value to add to element
cnt=0           ## flag to track delimiters found
num=

## for each character in str
for ((i = 0; i < ${#str}; i++))
do
    if [ "${str:$i:1}" = '.' -o "${str:$i:1}" = '-' ]   ## is it '.' or '-'
    then
        (( cnt++ ))                 ## increment count
        (( cnt == ele )) && break   ## if equal to ele, break

    ## check each char is a valid digit 0-9
    elif [ "0" -le "${str:$i:1}" -a "${str:$4i:1}" -le "9" ]
    then
        (( cnt == (ele - 1) )) || continue  ## it not one of interest, continue
        num="$num${str:$i:1}"               ## append digit to num
    fi
done

((num += add))  ## add the amount to num

printf "num: %d\n" $num     ## print results

示例使用/输出

$ bash parsenum.sh
num: 5122

$ bash parsenum.sh "1001.2001.3001.5001.6001" 2
num: 2122

$ bash parsenum.sh "1001.2001.3001.5001.6001" 2 221
num: 2222

仔细看看,如果您有任何问题,请告诉我。

相关问题