a*และ*a*ไวยากรณ์ดำเนินการโดยเปลือกที่ไม่ได้ตามlsคำสั่ง
เมื่อคุณพิมพ์
ls a*
ที่พรอมต์เปลือกของคุณเปลือกขยายไปยังรายการของแฟ้มที่มีอยู่ทั้งหมดในไดเรกทอรีปัจจุบันมีชื่อขึ้นต้นด้วยa* aยกตัวอย่างเช่นมันอาจขยายa*ลำดับและผ่านเหล่านั้นเป็นข้อโต้แย้งa1 a2 a3 คำสั่งตัวเองไม่เคยเห็นตัวละคร; เพียงเห็นอาร์กิวเมนต์ที่สาม, และlsls*a1a2a3
สำหรับวัตถุประสงค์ของการขยายสัญลักษณ์ "ไฟล์" หมายถึงเอนทิตีทั้งหมดในไดเรกทอรีปัจจุบัน ตัวอย่างเช่นa1อาจเป็นไฟล์ปกติa2อาจเป็นไดเรกทอรีและa3อาจเป็น symlink พวกเขาทั้งหมดมีรายการไดเรกทอรีและการขยายตัวแทนของเชลล์ไม่สนใจประเภทของรายการที่อ้างถึงเอนทิตี
แทบทุกเชลล์ที่คุณน่าจะใช้งานได้ (bash, sh, ksh, zsh, csh, tcsh, ... ) ใช้สัญลักษณ์แทน รายละเอียดอาจแตกต่างกัน แต่ไวยากรณ์พื้นฐานของการ*จับคู่ศูนย์หรือมากกว่าตัวอักษรและการ?จับคู่อักขระเดี่ยวใด ๆ มีความสอดคล้องกันอย่างสมเหตุสมผล
สำหรับ bash โดยเฉพาะจะมีการบันทึกไว้ในส่วน "การขยายชื่อไฟล์" ของคู่มือทุบตี เรียกใช้info bashและค้นหา "การขยายตัวของชื่อไฟล์" หรือดูที่นี่
ความจริงที่ว่าสิ่งนี้ทำโดยเชลล์และไม่ใช่ตามคำสั่งแต่ละคำสั่งมีผลที่น่าสนใจ (และบางครั้งก็น่าประหลาดใจ) สิ่งที่ดีที่สุดเกี่ยวกับการจัดการสัญลักษณ์แทนนั้นสอดคล้องกับคำสั่งเกือบทั้งหมด หากเชลล์ไม่ได้ทำสิ่งนี้ย่อมมีคำสั่งบางอย่างที่จะไม่รบกวนและอื่น ๆ จะทำมันในวิธีที่แตกต่างกันอย่างละเอียดที่ผู้เขียนคิดว่า "ดีกว่า" (ฉันคิดว่าเชลล์คำสั่ง Windows มีปัญหานี้ แต่ฉันไม่คุ้นเคยที่จะคอมเม้นท์เพิ่มเติม)
ในทางกลับกันก็ยากที่จะเขียนคำสั่งเพื่อเปลี่ยนชื่อหลายไฟล์ ถ้าคุณเขียน:
mv *.log *.log.bak
มันอาจจะล้มเหลวเนื่องจาก*.log.bakถูกขยายตามไฟล์ที่มีอยู่แล้วในไดเรกทอรีปัจจุบัน มีคำสั่งที่ทำสิ่งนี้ แต่พวกเขาต้องใช้ไวยากรณ์ของตัวเองเพื่อระบุวิธีการเปลี่ยนชื่อไฟล์ คำสั่งบางคำสั่ง (เช่นfind) สามารถทำการขยายสัญลักษณ์แทนของตนเองได้ คุณต้องอ้างอาร์กิวเมนต์เพื่อระงับการขยายตัวของเชลล์:
find . -name '*.txt' -print
การขยาย wildcard ของเชลล์ขึ้นอยู่กับไวยากรณ์ของอาร์กิวเมนต์บรรทัดคำสั่งและชุดของไฟล์ที่มีอยู่ทั้งหมด มันไม่สามารถรับผลกระทบจากความหมายของคำสั่ง ตัวอย่างเช่นหากคุณต้องการย้าย.logไฟล์ทั้งหมดไปยังไดเรกทอรีหลักคุณสามารถพิมพ์:
mv *.log ..
หากคุณลืม..:
mv *.log
และมี.logไฟล์สองไฟล์ในไดเรกทอรีปัจจุบันซึ่งจะขยายเป็น:
mv one.log two.log
ซึ่งจะเปลี่ยนชื่อและข่มขี่one.logtwo.log
แก้ไข : และหลังจาก 52 upvotes, การยอมรับและตรา Guru บางทีฉันควรตอบคำถามในชื่อ
-dหรือ--directoryเลือกที่จะlsไม่บอกให้รายการไดเรกทอรีเท่านั้น มันบอกให้รายการไดเรกทอรีเช่นเดียวกับตัวเองไม่ใช่เนื้อหาของพวกเขา หากคุณให้ชื่อไดเรกทอรีเป็นอาร์กิวเมนต์lsโดยค่าเริ่มต้นมันจะแสดงรายการเนื้อหาของไดเรกทอรีเนื่องจากปกติแล้วเป็นสิ่งที่คุณสนใจ-dตัวเลือกจะบอกให้แสดงเฉพาะไดเรกทอรีเท่านั้น สิ่งนี้มีประโยชน์อย่างยิ่งเมื่อรวมกับอักขระตัวแทน หากคุณพิมพ์:
ls -l a*
lsจะทำให้คุณมีรายชื่อยาวของแต่ละไฟล์ชื่อซึ่งเริ่มต้นด้วยaและของเนื้อหาaของแต่ละไดเรกทอรีที่มีชื่อขึ้นต้นด้วย หากคุณต้องการรายการไฟล์และไดเรกทอรีหนึ่งบรรทัดสำหรับแต่ละไฟล์คุณสามารถใช้:
ls -ld a*
ซึ่งเทียบเท่ากับ:
ls -l -d a*
จำอีกครั้งว่าlsคำสั่งไม่เคยเห็น*ตัวละคร
สำหรับตำแหน่งที่จัดทำเอกสารนี้man lsจะแสดงเอกสารสำหรับlsคำสั่งเกี่ยวกับระบบ Unix ที่คล้ายกัน บนระบบที่ใช้ Linux ส่วนใหญ่lsคำสั่งเป็นส่วนหนึ่งของแพ็คเกจ GNU coreutils หากคุณมีinfoคำสั่งอย่างใดอย่างหนึ่งinfo lsหรือinfo coreutils lsควรให้เอกสารที่ชัดเจนและครอบคลุมมากขึ้น ระบบอื่น ๆ เช่น MacOS อาจใช้lsคำสั่งเวอร์ชันต่าง ๆและอาจไม่มีinfoคำสั่ง man lsสำหรับระบบที่ใช้ และls --helpจะแสดงข้อความการใช้งานที่ค่อนข้างสั้น (117 บรรทัดบนระบบของฉัน) หากคุณกำลังใช้การใช้งาน coreutils ของ GNU
และแม้กระทั่งผู้เชี่ยวชาญก็จำเป็นต้องอ่านเอกสารนี้แล้ว ดูมุกตลกคลาสสิกนี้ด้วย