Como remover um parâmetro posicional de $ @

13

Basicamente, quero "extrair" a primeira ocorrência da -inflista de parâmetros. (Os parâmetros restantes serão passados ​​para um comando diferente.)

O script que eu tenho tem a seguinte estrutura:

#!/bin/sh

<CODE>

for POSITIONAL_PARAM in "$@"
do

    <CODE>

    if [ "$POSITIONAL_PARAM" = '-inf' ]
    then
        <PLUCK $POSITIONAL_PARAM FROM $@>
        break
    fi

    <CODE>

done

<CODE>

some-other-command "$@"

# end of script

Existe uma boa maneira de fazer isso?

BTW, embora eu esteja interessado principalmente em respostas aplicáveis ​​a /bin/sh , também estou interessado nas respostas aplicáveis ​​apenas a /bin/bash.

kjo
fonte
@cuonglm: Eu voltei à forma original do pseudo-código; na minha experiência, sempre que simplifico demais a imagem, recebo respostas que funcionam para o caso simplificado demais, mas não para o real.
KJo

Respostas:

20

POSIXly:

for arg do
  shift
  [ "$arg" = "-inf" ] && continue
  set -- "$@" "$arg"
done

printf '%s\n' "$@"

O código acima até funciona em shells pré-POSIX, exceto o shell Almquist original (Read Endnote ). Mude o forloop para:

for arg
do
  ...
done

garantir o trabalho em todas as conchas.


Outro POSIX:

for arg do
  shift
  case $arg in
    (-inf) : ;;
       (*) set -- "$@" "$arg" ;;
  esac
done

Com este, você precisa remover o primeiro (em (pattern)fazê-lo funcionar em conchas pré-POSIX.

cuonglm
fonte
Obrigado. Essa técnica de ciclismo de argumentos é muito boa. Ele tem o bônus adicional de facilitar a inspeção do parâmetro após o atual (já que ele está bem ali $1). Essa propriedade foi útil no que estou fazendo. Além disso, obrigado por me lembrar que a parte in "$@"; no topo do forloop é desnecessária. É algo que eu já vi antes, mas costumo esquecer. Em relação à sua observação sobre a concha Almquist, ela do precisa aparecer na próxima linha ou for arg; dofuncionaria também?
KJo
1
for arg; dotrabalho em Almquist shell
cuonglm
2
Para os não iniciados, for arg doé uma expressão abreviada para for arg in "$@"; do. Isso me jogou por cerca de 5 segundos! Alguns podem dizer que o último é mais legível :)
starfry
0

Encontrei essa pergunta enquanto tentava resolver um problema semelhante, mas queria processar todos os argumentos que não são de opção (aqueles que não começam com -) até os recebidos.-- separador . Eu queria extrair apenas os argumentos processados ​​e deixar os restantes in situ na ordem fornecida.

Aqui está o que eu criei.

parse=true
for arg do
  [ "$arg" == '--' ] && parse=false
  shift
  if $parse && [ "${arg:0:1}" != '-' ]
  then
    echo handling $arg
  else
    set -- "$@" "$arg"
  fi
done
starfry
fonte