Як видалити позиційний параметр з $ @


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

Чи є хороший спосіб це зробити?

BTW, хоча мене в основному цікавлять відповіді, застосовні до /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

3
Для непосвячених for arg do- це скорочена ідіома для for arg in "$@"; do. Це кинуло мене близько 5 секунд! Дехто може сказати, що останнє легше читати :)
starfry

0

Я знайшов це питання, намагаючись вирішити подібну проблему, однак хотів обробити всі необов'язкові аргументи (ті, що не починаються з -) до будь-якого отриманого --роздільника. Я хотів вирвати лише оброблені аргументи і залишити решту in situ у наданому порядку.

Ось що я придумав.

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.