Excluindo o último argumento / parâmetro de um loop for

4

Eu estou olhando para criar um script de shell que irá percorrer cada argumento / parâmetro, exceto para o último. Aqui está o que eu tenho até agora:

for i in $@
do
      echo "$i"
done

Isso funciona bem em termos de exibir todos os argumentos depois do meu comando ./script.sh, mas espero que haja uma maneira de ignorar o último parâmetro ou até mesmo qualquer parâmetro de minha escolha (por exemplo, ignorando sempre o terceiro parâmetro). parâmetro se houver um). Para ser claro, estou mais preocupado com o último parâmetro / argumento por enquanto.

Sou novo em scripts, por isso peço desculpas se houver outra postagem que contenha essa resposta. Eu acho que ser novo em algo geralmente significa que você não sabe como perguntar corretamente o que você está procurando.

Qualquer ajuda seria muito apreciada!

    
por Syrum 25.03.2017 / 18:30

4 respostas

8

Se você não precisa manter os parâmetros

while (( $# > 1 ))
do
  echo "$1"
  shift
done

Se você quiser manter inalterados os parâmetros posicionais, poderá manter uma contagem

SKIP=$#

let x=1

for i
do
  if (( x != SKIP ))
  then
    echo "$i"
  fi
  let x=x+1
done
    
por 25.03.2017 / 18:45
9

O CentOS provavelmente tem o Bash, então, se você puder usá-lo, poderá percorrer uma fatia do array:

for x in "${@:1:$# - 1}" ; do 
    echo do something with "$x"
done

A% de${@:n:m} de notação recebe o m posicional parâmetros começando no número n . Nós escolhemos seu número total de $# e decrementamos por um para ignorar o último parâmetro. O offset e o comprimento são tomados como expressões aritméticas como em $((...)) , então podemos fazer a aritmética ali mesmo, como Stéphane comentou abaixo. Os índices das matrizes geralmente começam do zero, mas no caso de $@ , começando em zero, o nome do shell de $0 é trazido e não é isso que queremos.

Note que é altamente provável que você queira citar as expressões $@ ou ${@:n:m} para evitar que seus argumentos sejam divididos ainda mais.

    
por 25.03.2017 / 18:53
3
skip_last() {
   p=$1; shift

   for i
   do
      set ${1+"$@"} "$p"; p=$1; shift
   done

   for i
   do
      # do something with i when i != last now
      echo "$i"
   done
}
# and then...
skip_last "a" "b" "c" "d" "e"
    
por 25.03.2017 / 19:12
3

Você pode usar um loop que define um variável i a 1 , 2 , ... n-1 e usar expansão indireta para transformar isso em $1 , $2 , ..., $n-1 .

for ((i=1; i<$#; i++)); do
    echo "${!i}"
done
    
por 25.03.2017 / 19:26

Tags