วิธีลบพารามิเตอร์ตำแหน่งจาก $ @


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' "$@"

รหัสข้างต้นยังใช้งานได้ในเชลล์ pre-POSIX ยกเว้นเชลล์ Almquist ดั้งเดิม (อ่าน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 shell
cuonglm

3
สำหรับ unininitiated เป็นสำนวนชวเลข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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.