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.


@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.


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.