Cara menghapus parameter posisi dari $ @

13

Pada dasarnya, saya ingin "mencabut" kejadian pertama dari -infdaftar parameter. (Parameter yang tersisa akan diteruskan ke perintah yang berbeda.)

Skrip yang saya miliki memiliki struktur sebagai berikut:

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

Apakah ada cara yang baik untuk melakukan ini?

BTW, meskipun saya terutama tertarik pada jawaban yang berlaku untuk /bin/sh, saya juga tertarik pada jawaban yang hanya berlaku untuk /bin/bash.

kjo
sumber
@cuonglm: Saya telah kembali ke bentuk asli dari kode semu; dalam pengalaman saya, setiap kali saya menyederhanakan gambar terlalu banyak, saya mendapatkan jawaban yang berfungsi untuk kasus yang terlalu disederhanakan, tetapi tidak untuk yang sebenarnya.
kjo

Jawaban:

20

POSIXly:

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

printf '%s\n' "$@"

Kode di atas bahkan bekerja di shell pra-POSIX, kecuali shell Almquist asli (Baca Catatan Akhir ). Ubah forloop ke:

for arg
do
  ...
done

jaminan untuk bekerja di semua kerang.


Satu lagi POSIX:

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

Dengan yang satu ini, Anda harus menghapus pertama (di (pattern)untuk membuatnya bekerja pada kulit pra-POSIX.

cuonglm
sumber
Terima kasih. Teknik bersepeda argumen itu sangat bagus. Ini memiliki bonus tambahan yang membuatnya sangat mudah untuk memeriksa parameter mengikuti yang sekarang (karena itu hanya duduk di sana $1). Properti ini sangat berguna dalam apa yang saya lakukan. Juga, terima kasih telah mengingatkan saya bahwa in "$@"; bit di bagian atas forloop tidak perlu. Itu adalah sesuatu yang pernah saya lihat sebelumnya, tetapi saya cenderung melupakannya. Mengenai komentar Anda di shell Almquist, apakah do harus muncul di baris berikutnya, atau akan for arg; dobekerja juga?
kjo
1
for arg; dobekerja di shell Almquist
cuonglm
2
Bagi yang belum tahu for arg doadalah ungkapan singkat untuk for arg in "$@"; do. Itu membuat saya sekitar 5 detik! Beberapa orang mungkin mengatakan yang terakhir ini lebih mudah dibaca :)
starfry
0

Saya menemukan pertanyaan ini ketika mencoba menyelesaikan masalah yang sama, namun saya ingin memproses semua argumen non-opsi (yang tidak dimulai dengan -) hingga --pemisah yang diterima . Saya ingin mencabut argumen yang diproses saja dan membiarkan yang tersisa di situ dalam urutan yang disediakan.

Inilah yang saya pikirkan.

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