Cómo eliminar un parámetro posicional de $ @

13

Básicamente, quiero "extraer" la primera aparición de -infla lista de parámetros. (Los parámetros restantes se pasarán a un comando diferente).

El script que tengo tiene la siguiente estructura:

#!/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 una forma correcta de hacer esto?

Por cierto, aunque estoy interesado principalmente en respuestas aplicables a /bin/sh, también estoy interesado en respuestas aplicables solo a /bin/bash.

kjo
fuente
@cuonglm: he vuelto a la forma original del pseudocódigo; En mi experiencia, cada vez que simplifico demasiado la imagen, obtengo respuestas que funcionan para el caso simplificado en exceso, pero no para el caso real.
kjo

Respuestas:

20

POSIXY:

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

printf '%s\n' "$@"

El código anterior incluso funciona en shells anteriores a POSIX, excepto el shell original de Almquist (Lea la nota final ). Cambia el forciclo a:

for arg
do
  ...
done

Garantía para trabajar en todos los depósitos.


Otro POSIX:

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

Con éste, es necesario eliminar la primera (en (pattern)hacer que funcione en las conchas de pre-POSIX.

Cuonglm
fuente
Gracias. Esa técnica de ciclismo es muy buena. Tiene la ventaja adicional de que hace que sea muy fácil inspeccionar el parámetro que sigue al actual (ya que solo está ahí $1). Esta propiedad fue útil en lo que estoy haciendo. Además, gracias por recordarme que el in "$@"; bit en la parte superior del forbucle es innecesario. Es algo que he visto antes, pero tiendo a olvidarlo. Con respecto a su comentario sobre el caparazón de Almquist, ¿ do tiene que aparecer en la siguiente línea, o for arg; dofuncionaría también?
kjo
1
for arg; dotrabajo en el caparazón de Almquist
cuonglm
2
Para los no iniciados for arg does un lenguaje abreviado para for arg in "$@"; do. ¡Eso me arrojó por unos 5 segundos! Algunos podrían decir que este último es más legible :)
starfry
0

Encontré esta pregunta al intentar resolver un problema similar, sin embargo, quería procesar todos los argumentos que no son de opción (aquellos que no comienzan con -) hasta cualquier --separador recibido . Solo quería extraer los argumentos procesados ​​y dejar los restantes in situ en el orden proporcionado.

Esto es lo que se me ocurrió.

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