Jak usunąć parametr pozycyjny z $ @


13

Zasadniczo chcę „wyciągnąć” pierwsze wystąpienie -infz listy parametrów. (Pozostałe parametry zostaną przekazane do innego polecenia.)

Skrypt, który mam, ma następującą strukturę:

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

Czy jest na to dobry sposób?

BTW, chociaż interesują mnie głównie odpowiedzi dotyczące /bin/sh, interesują mnie również odpowiedzi dotyczące tylko /bin/bash.


@cuonglm: Powróciłem do oryginalnej formy pseudo kodu; z własnego doświadczenia, ilekroć za bardzo upraszczam obraz, otrzymuję odpowiedzi, które działają w przypadku uproszczonego, ale nie w przypadku rzeczywistego.
kjo

Odpowiedzi:


20

POSIXly:

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

printf '%s\n' "$@"

Powyższy kod działa nawet w powłokach wcześniejszych niż POSIX, z wyjątkiem oryginalnej powłoki Almquist (Read Endnote ). Zmień forpętlę na:

for arg
do
  ...
done

gwarancja pracy we wszystkich powłokach.


Kolejny POSIX:

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

Z tym jednym, trzeba usunąć pierwszy (w (pattern), aby pracować w muszli pre-POSIX.


Dzięki. Ta technika jazdy na argumentach jest bardzo przyjemna. Ma dodatkową zaletę, dzięki której bardzo łatwo można sprawdzić parametr następujący po bieżącym (ponieważ on po prostu tam siedzi $1). Ta właściwość przydała się w tym, co robię. Ponadto dziękuję za przypomnienie, że in "$@"; bit u góry forpętli jest niepotrzebny. Widziałem to wcześniej, ale zwykle o tym zapominam. Jeśli chodzi o twoją uwagę na temat powłoki Almquist, czy do musi ona pojawić się w następnym wierszu, czy for arg; doteż zadziała?
kjo

1
for arg; dopraca w skorupie Almquista
cuonglm

3
Dla niewtajemniczonych for arg dojest skrótem dla for arg in "$@"; do. To rzuciło mnie na około 5 sekund! Niektórzy mogą powiedzieć, że ten drugi jest bardziej czytelny :)
starfry

0

Znalazłem to pytanie, próbując rozwiązać podobny problem, jednak chciałem przetworzyć wszystkie argumenty inne niż opcje (te, które nie zaczynają się od -) do dowolnego otrzymanego --separatora. Chciałem wyłapać tylko przetworzone argumenty i pozostawić pozostałe na miejscu w podanej kolejności.

Oto, co wymyśliłem.

parse=true
for arg do
  [ "$arg" == '--' ] && parse=false
  shift
  if $parse && [ "${arg:0:1}" != '-' ]
  then
    echo handling $arg
  else
    set -- "$@" "$arg"
  fi
done
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.