Как удалить позиционный параметр из $ @


13

По сути, я хочу «вырвать» первое вхождение -infиз списка параметров. (Остальные параметры будут переданы другой команде.)

Сценарий, который у меня есть, имеет следующую структуру:

#!/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

Есть ли хороший способ сделать это?

Кстати, хотя меня в основном интересуют ответы, применимые к /bin/sh, меня также интересуют ответы, применимые только к /bin/bash.


@cuonglm: я вернулся к первоначальной форме псевдокода; по моему опыту, всякий раз, когда я слишком упрощаю картину, я получаю ответы, которые работают для упрощенного случая, но не для фактического.
kjo

Ответы:


20

POSIXly:

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

printf '%s\n' "$@"

Приведенный выше код работает даже в оболочках до POSIX, за исключением оригинальной оболочки Almquist (Read Endnote ). Измените forцикл на:

for arg
do
  ...
done

гарантия на работу во всех снарядах.


Еще один POSIX:

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

С этим, вы должны удалить первый (в , (pattern)чтобы заставить его работать в предварительно POSIX оболочек.


Благодарю. Техника езды на велосипеде аргумента очень хороша. У него есть дополнительный бонус, который позволяет очень легко проверить параметр, следующий за текущим (так как он просто находится прямо там $1). Это свойство пригодилось в том, что я делаю. Также спасибо за напоминание, что in "$@"; бит в верхней части forцикла не нужен. Это то, что я видел раньше, но я склонен забывать это. Что касается вашего замечания по оболочке Almquist, do должен ли он отображаться на следующей строке или for arg; doтоже будет работать?
kjo

1
for arg; doработа в оболочке Almquist
cuonglm

2
Для непосвященных for arg doэто сокращенная идиома for arg in "$@"; do. Это бросило меня на 5 секунд! Кто-то скажет, что последнее более читабельно :)
starfry

0

Я нашел этот вопрос, пытаясь решить аналогичную проблему, однако я хотел обработать все неопционные аргументы (те, которые не начинаются с -) до любого полученного --разделителя. Я хотел вынуть только обработанные аргументы и оставить оставшиеся на месте в указанном порядке.

Вот что я придумал.

parse=true
for arg do
  [ "$arg" == '--' ] && parse=false
  shift
  if $parse && [ "${arg:0:1}" != '-' ]
  then
    echo handling $arg
  else
    set -- "$@" "$arg"
  fi
done
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.