หากในกรณีที่คุณไม่ได้ใช้งานคุณเพียงแค่พยายามจัดการอัญประกาศเพื่อนำเปลือกไอออนกลับมาใช้ใหม่คุณสามารถทำได้โดยไม่ต้องลบมันออกและมันก็ง่ายเกินไปเช่นกัน:
aq() { sh -c 'for a do
alias "$((i=$i+1))=$a"
done; alias' -- "$@"
}
ฟังก์ชั่นของเชลล์นั้นเสนอราคาอาเรย์หาเรื่องใด ๆ ที่คุณมอบและเพิ่มเอาท์พุทของมันสำหรับแต่ละอาร์กิวเมนต์
ที่นี่มันมี args ไม่กี่:
aq \
"here's an
ugly one" \
"this one is \$PATHpretty bad, too" \
'this one```****```; totally sucks'
เอาท์พุท
1='here'"'"'s an
ugly one'
2='this one is $PATHpretty bad, too'
3='this one```****```; totally sucks'
ผลลัพธ์ที่ได้จากซึ่งมักจะปลอดภัยคำพูดเอาท์พุทเดียวที่ยกมาเช่นdash จะทำอย่างไร '"'"'bash'\''
การเปลี่ยนการเลือกเดียวที่ไม่ใช่ช่องว่างที่ไม่ใช่ null ไบต์กับอีก byte เดียวจะสามารถทำได้เร็วที่สุดใน POSIX เปลือกและ$IFS$*
set -f; IFS=\"\'\`; set -- $var; printf %s "$*"
เอาท์พุท
"some ""crazy """"""""string ""here
ที่นั่นฉันเพียงแค่printfมันเพื่อให้คุณสามารถดู แต่แน่นอนถ้าฉันได้ทำ:
var="$*"
... แทนที่จะเป็นค่าของprintfคำสั่ง$varจะเป็นสิ่งที่คุณเห็นในผลลัพธ์ที่นั่น
เมื่อฉันset -fฉันสั่งเปลือกไม่ให้ glob - ในกรณีที่สตริงมีตัวอักษรที่สามารถตีความได้ว่าเป็นรูปแบบ glob ฉันทำเช่นนี้เพราะ shell parser ขยายรูปแบบ glob หลังจากที่ดำเนินการแยกฟิลด์กับตัวแปร globbing set +fสามารถเปิดใช้งานเช่น โดยทั่วไป - เป็นสคริปต์ - ฉันพบว่ามีประโยชน์ในการตั้งค่าปังของฉันเช่น:
#!/usr/bin/sh -f
และจากนั้นให้เปิดใช้งาน globbing อย่างชัดเจนกับset +fสิ่งที่ฉันอาจต้องการมัน
$IFSแยกสนามเกิดขึ้นบนพื้นฐานของตัวละครใน
มีสองประเภทของ$IFSค่าคือ - $IFSช่องว่างและช่องว่างที่$IFSไม่ใช่ $IFSช่องว่างที่คั่นด้วยช่องว่าง(ช่องว่าง, แท็บบรรทัดใหม่)ถูกระบุให้ตัดตามลำดับในฟิลด์เดียว(หรือไม่มีเลยถ้าพวกเขาไม่นำหน้าอย่างอื่น) - ดังนั้น ...
IFS=\ ; var=' '; printf '<%s>' $var
<>
แต่คนอื่น ๆ ทั้งหมดจะถูกระบุให้ประเมินเป็นเขตข้อมูลเดียวต่อเหตุการณ์ที่เกิดขึ้น - พวกเขาจะไม่ถูกตัดทอน
IFS=/; var='/////'; printf '<%s>' $var
<><><><><>
ทั้งหมดขยายตัวแปรตามค่าเริ่มต้น$IFSที่คั่นอาร์เรย์ข้อมูล - $IFSพวกเขาแยกออกไปแยกทุ่งตาม เมื่อคุณ - "พูดถึงสิ่งที่คุณแทนที่คุณสมบัติอาร์เรย์นั้นและประเมินเป็นสตริงเดียว
ดังนั้นเมื่อฉันทำ ...
IFS=\"\'\`; set -- $var
ฉันกำลังตั้งค่าอาเรย์อาร์กิวเมนต์ของเชลล์ไปยัง$IFSฟิลด์ที่มีตัวคั่นจำนวนมากซึ่งเกิดจาก$varการขยายตัวของ เมื่อได้มีการขยายค่าที่เป็นส่วนประกอบของตัวละครที่มีอยู่ใน$IFSจะหายไป - พวกเขาเป็นเพียงตัวคั่นฟิลด์ในขณะนี้ - \0NULพวกเขามี
"$*"- เหมือนยกมาสองครั้งตัวแปรขยายอื่น ๆ - $IFSยังแทนที่คุณภาพฟิลด์แยกของ แต่นอกเหนือจากนั้นมันทดแทนไบต์แรกใน$IFS แต่ละสนามคั่น"$@"ใน ดังนั้นเพราะ"เป็นครั้งแรกที่ค่าใน$IFS ทุกตัวคั่นต่อมากลายเป็นใน" "$*"และ"ไม่จำเป็นต้องอยู่ใน$IFSเมื่อคุณแยกมันเช่นกัน คุณสามารถปรับเปลี่ยน$IFS หลังจาก set -- $argsค่าอื่นทั้งหมดและของใหม่"$*"ไบต์แรกจากนั้นก็จะแสดงขึ้นสำหรับตัวคั่นสนามใน ยิ่งไปกว่านั้นคุณสามารถลบร่องรอยทั้งหมดเช่น:
set -- $var; IFS=; printf %s "$*"
เอาท์พุท
some crazy string here
trต่อไป PE ของ BASH นั้นดี แต่ TR นั้นเร็วกว่ามากในกรณีนี้ เช่นecho "$OUTPUT" | tr -dc '[[:alpha:]]'เนื่องจากคุณต้องการมีตัวอักษรและตัวเลขเท่านั้น