Alterando um número em uma string de números

4

Estou tentando escrever uma função que me permita alterar um número em uma lista de números com base em uma posição. Por exemplo, eu quero poder alterar o quarto número na lista 10.90.123.80.42 para 19 para que eu receba 10.90.123.19.42 .

Estou querendo algo ao longo das linhas:

NUMBERLIST=10.90.123.80.42
changeNumberByPosition "$NUMBERLIST" "4" "19"
echo $NUMBERLIST

10.90.123.19.42

Desculpe se esta é uma pergunta simples, mas eu sou relativamente novo no script e qualquer ajuda que eu pudesse obter seria apreciada.

    
por Adam L 08.05.2017 / 16:26

2 respostas

5

Usando o awk:

function changeNumberByPosition { 
  echo | string=$1 position=$2 newvalue=$3 \
    awk -v FS=. -v OFS=.  '{ 
      $0=ENVIRON["string"]; 
      $ENVIRON["position"]=ENVIRON["newvalue"]; 
      print;
   }';
}

Execução da amostra:

NUMBERLIST=10.90.123.80.42
new=$(changeNumberByPosition "$NUMBERLIST" 4 19)
echo "$new"
10.90.123.19.42

ou para atualizar o valor existente com um novo valor:

NUMBERLIST=10.90.123.80.42
NUMBERLIST=$(changeNumberByPosition "$NUMBERLIST" 4 19)
echo "$NUMBERLIST"
10.90.123.19.42

Usando o bash v4 +:

function changeNumberByPosition ( 
  set -o noglob
  IFS=. 
  a=($1); 
  a[$2]=$3;
  printf '%s\n' "${a[*]}" 
)

A versão somente bash da função:

  1. divide o primeiro parâmetro (por exemplo, $ NUMBERLIST) em uma matriz a , com base em períodos, usando o IFS.
  2. substitui o parâmetro $2 pelo valor em $3 .
  3. imprime os primeiros elementos N-1 da matriz, cada um seguido de um ponto e depois imprime o último elemento da matriz.
  4. faz tudo isso em um subshell, de modo que $a não atrapalha o ambiente existente.
por 08.05.2017 / 16:50
5

com zsh :

NUMBERLIST=10.90.123.80.42
typeset -T NUMBERLIST numberlist . # tie $NUMBERLIST variable to $numberlist array
                                   # in a similar fashion as $PATH is tied to
                                   # $path, but here using "." instead of ":" as
                                   # the separator
numberlist[4]=19
printf '%s\n' $NUMBERLIST # with updated 4th field.

Você também pode dividir e unir manualmente:

NUMBERLIST=10.90.123.80.42
list=("${(@s:.:)NUMBERLIST}")
list[4]=19
NUMBERLIST=${(j:.:)list}
printf '%s\n' $NUMBERLIST
    
por 08.05.2017 / 17:06