Cách xóa tham số vị trí khỏi $ @


13

Về cơ bản, tôi muốn "nhổ" sự xuất hiện đầu tiên của -infdanh sách tham số. (Các tham số còn lại sẽ được truyền cho một lệnh khác.)

Kịch bản tôi có cấu trúc sau:

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

Có một cách tốt để làm điều này?

BTW, mặc dù tôi chủ yếu quan tâm đến câu trả lời áp dụng cho /bin/sh, tôi cũng quan tâm đến câu trả lời chỉ áp dụng cho /bin/bash.


@cuonglm: Tôi đã trở lại dạng ban đầu của mã giả; theo kinh nghiệm của tôi, bất cứ khi nào tôi đơn giản hóa bức tranh quá nhiều, tôi sẽ nhận được câu trả lời phù hợp với trường hợp đơn giản hóa, nhưng không phải cho trường hợp thực tế.
kjo

Câu trả lời:


20

POSIXly:

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

printf '%s\n' "$@"

Đoạn mã trên thậm chí hoạt động trong các vỏ trước POSIX, ngoại trừ vỏ Almquist gốc (Đọc chú thích ). Thay đổi forvòng lặp thành:

for arg
do
  ...
done

đảm bảo làm việc trong tất cả các vỏ.


Một POSIX khác:

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

Với một cú này, bạn cần phải loại bỏ đầu tiên (trong (pattern)để làm cho nó làm việc trong vỏ trước POSIX.


Cảm ơn. Đó là kỹ thuật đi xe đạp đối số là rất tốt đẹp. Nó có phần thưởng bổ sung rằng nó giúp bạn dễ dàng kiểm tra tham số theo thông số hiện tại (vì nó chỉ ngồi ngay tại đó $1). Khách sạn này có ích trong những gì tôi đang làm. Ngoài ra, cảm ơn vì đã nhắc nhở tôi rằng in "$@"; bit ở đầu forvòng lặp là không cần thiết. Đó là thứ tôi đã thấy trước đây, nhưng tôi có xu hướng quên nó đi. Về nhận xét của bạn về vỏ Almquist, liệu do phải xuất hiện trên dòng tiếp theo, hoặc cũng sẽ for arg; dohoạt động?
kjo

1
for arg; dolàm việc trong vỏ Almquist
cuonglm

2
Đối với người không quen biết for arg dolà một thành ngữ tốc ký cho for arg in "$@"; do. Điều đó đã ném tôi trong khoảng 5 giây! Một số người có thể nói cái sau dễ đọc hơn :)
starfry 20/1/2017

0

Tôi đã tìm thấy câu hỏi này trong khi cố gắng giải quyết một vấn đề tương tự, tuy nhiên tôi muốn xử lý tất cả các đối số không phải tùy chọn (những đối số không bắt đầu -) cho đến bất kỳ --dấu tách nào nhận được . Tôi muốn chỉ rút ra các đối số được xử lý và để các đối số còn lại vào vị trí theo thứ tự được cung cấp.

Đây là những gì tôi đã đưa ra.

parse=true
for arg do
  [ "$arg" == '--' ] && parse=false
  shift
  if $parse && [ "${arg:0:1}" != '-' ]
  then
    echo handling $arg
  else
    set -- "$@" "$arg"
  fi
done
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.