φυβλαςのβλογ
phyblasのブログ



การใช้ glob เพื่อค้นหาไฟล์ที่ต้องการใน shell
เขียนเมื่อ 2019/01/09 18:08
แก้ไขล่าสุด 2021/09/28 16:42
ปกติเวลาที่เราใช้คำสั่งจัดการพวกไฟล์ต่างๆภายในเชลทีละหลายๆไฟล์มักจะมีการใช้สัญลักษณ์ดอกจัน * ในการเขียน

เช่นเวลาที่ต้องการแสดงชื่อไฟล์ .jpg ทั้งหมดในเชลจะพิมพ์ว่า ls *.jpg

ในที่นี้ * แทนตัวหนังสืออะไรก็ได้ ดังนั้นไฟล์อะไรก็ตามที่ชื่อลงท้ายด้วย .jpg จึงเข้าข่ายหมด

วิธีการเขียนแบบนี้เรียกว่ากล็อบ (glob) ส่วนดอกจัน * ในที่นี้เรียกว่าไวลด์การ์ด (wild card)

กล็อบเป็นรูปแบบการเขียนเพื่อคัดกรองข้อความที่เข้าข่าย มักถูกใช้ในการจัดการข้อความต่างๆในระบบเชลยูนิกซ์ แต่ก็ถูกใช้ในที่อื่นอย่างกว้างขวาง ในภาษาไพธอนเองก็มีคำสั่งที่ดึงมาใช้ได้สะดวกเช่นกัน

นอกจากการใช้ * แล้ว ยังมีรูปแบบการเขียนอย่างอื่นอีก ซึ่งจะเขียนถึงต่อไปในบทความนี้

ในบทความนี้จะเริ่มจากอธิบายรูปแบบวิธีการเขียนกล็อบโดยทั่วไป ส่วนวิธีการใช้ในไพธอนอ่านได้ใน https://phyblas.hinaboshi.com/20190110





ดอกจัน *

สัญลักษณ์ดอกจัน * จะแทนอักษรอะไรกี่ตัวก็ได้ที่ไม่ใช่สแลช /

ที่ยกเว้น / เพราะ / เป็นสัญลักษณ์ที่เอาไว้กั้นระหว่างชื่อโฟลเดอร์กับชื่อไฟล์

เพียงแต่ถ้าเป็นใน windows ตัวยกเว้นจะเป็นแบ็กสแลช \ แทน เพราะ windows ใช้ \ ในการกั้นชื่อไฟล์

ในบทความนี้จะยกตัวอย่างด้วย mac และ linux เป็นหลัก เพราะเดิมทีกล็อบถูกใช้กับเชลยูนิกซ์เป็นหลัก

ยกตัวอย่างเช่น a* จะได้ชื่อไฟล์อะไรก็ตามที่ขึ้นต้นด้วย a เช่น aaa.txt ab.png

*.*g จะได้ไฟล์ที่เป็นสกุลที่ลงท้ายด้วย g ทั้งหมด เช่น bb.png cc.jpg แต่จะไม่ได้ hh.gif

เนื่องจาก * จะไม่รวม / ด้วย ดังนั้นถ้าจะหาไฟล์ที่อยู่ในโฟลเดอร์ย่อยให้เขียนเป็น */* แบบนี้ได้

เช่น */*.txt แบบนี้จะเป็นการค้นหาไฟล์ .txt ทุกไฟล์ในโฟลเดอร์ย่อยทั้งหมด



เครื่องหมายคำถาม ?

สำหรับเครื่องหมายคำถาม ? จะแทนอักษรอะไรก็ได้เพียงตัวเดียว

เช่น a?.txt จะเจอ ab.txt ak.txt แต่จะไม่เจอ aac.txt

ข้อแตกต่างกับดอกจัน * ก็คือเครื่องหมายคำถาม ? จะแทนแค่ตัวเดียวเสมอ แต่ดอกจัน * จะแทนกี่ตัวก็ได้แม้แต่ศูนย์ตัว

จะให้แทนอักษรกี่ตัวก็ใส่ ? ไปเท่านั้น

เช่นจะหาไฟล์ .txt อะไรก็ได้ที่ชื่อยาว ๓ ตัวก็ใช้ ???.txt แบบนี้ก็จะเจอ abc.txt ggg.txt ฯลฯ



วงเล็บเหลี่ยม [ ]

หากมีอักษรที่ต้องการค้นหาหลายตัวในทีเดียวมีวิธีการเขียนที่แสดงถึงอักษรนั้นตัวไหนก็ได้โดยมัดรวมอักษรที่ต้องการหาทั้งหมดไว้ในวงเล็บเหลี่ยม

เช่น [aei]n.txt แบบนี้จะเป็นการหาไฟล์ที่ชื่อ an.txt en.txt in.txt



เครื่องหมายตกใจ ! หรือ ^

ถ้าใส่ ! หรือ ^ ไว้ที่ด้านหน้าสุดภายในวงเล็บเหลี่ยมจะให้ผลในทางตรงกันข้าม คือจะแทนตัวอักษรตัวไหนก็ได้ที่ไม่อยู่ในนั้น

เช่น [^ab]* หรือ [!ab]* แบบนี้จะเจอชื่อไฟล์ไหนก็ได้ที่ไม่ได้ขึ้นต้นด้วย a หรือ b

ต่อให้มีอักษรที่ต้องการยกเว้นอยู่แค่ตัวเดียวก็ยังต้องใส่วงเล็บเหลี่ยมเช่นกัน เช่นถ้าจะเอาไฟล์ที่ไม่ได้ขึ้นต้นด้วย a ก็เป็น [^a]*

ในเชลปกติแล้วจะแยกตัวพิมพ์ใหญ่พิมพ์เล็ก ดังนั้นวิธีการเขียนแบบนี้ช่วยให้หาชื่อไฟล์ทั้งพิมพ์ใหญ่และพิมพ์เล็กได้ในขณะเดียวกัน

เช่น [aA][bB][cC].txt จะเจอ aBc.txt AbC.txt ABc.txt ฯลฯ

อย่างไรก็ตาม ในบางระบบอาจใช้ได้แค่ ^ หรือ ! อย่างใดอย่างหนึ่ง เช่นคำสั่ง glob ในไพธอนจะใช้ ! ไม่ใช้ ^



ขีด - ในวงเล็บเหลี่ยม

กรณีที่อักษรที่ต้องการค้นหลายๆตัวนั้นเป็นอักษรต่อเนื่องกัน อาจใช้ - เพื่อแทนอักษรทั้งหมดตั้งแต่ตัวซ้ายถึงตัวขวา

[a-i] จะแทนอักษรตั้งแต่ a,b,c,... ไปจนถึง i

หรือเลข [1-7] แบบนี้เป็นต้น

ตัวอย่างเช่น [c-e][3-5] แบบนี้จะเจอ c3 e4 d5 แต่จะไม่เจอ b4 b6 e2 เป็นต้น



แบ็กสแลช \

ทั้งเครื่องหมาย * และ ? ล้วนเป็นอักษรที่ใช้ตั้งเป็นชื่อไฟล์ได้ แต่ว่าเวลาค้นหาด้วยกล็อบกลับเป็นอักษรที่มีความหมายพิเศษ ดังนั้นถ้าต้องการหาแค่ชื่อไฟล์ที่เป็น * หรือ ? จะมีปัญหา

ดังนั้นถ้าค้นหาว่า a*.txt แทนที่จะเจอแค่ไฟล์ชื่อ a*.txt ก็กลับจะได้ไฟล์ ab.txt ax.txt มาด้วย

เพื่อแก้ปัญหานี้ ให้ใส่ \ นำหน้า * หรือ ?

เช่น a\*.txt แบบนี้จึงจะเป็นการหาแค่ไฟล์ a*.txt



เปรียบเทียบกับเรกูลาร์เอ็กซ์เพรชชัน

รูปแบบการเขียนของกล็อบมีส่วนคล้ายกับเรกูลาร์เอ็กซ์เพรชชัน (regular expression, รายละเอียดเรื่องนี้อ่านได้ใน https://phyblas.hinaboshi.com/20160922)

ที่คล้ายกันก็คือการใช้ดอกจัน * กับวงเล็บเหลี่ยม [] แต่ความหมายของเครื่องหมายคำถาม ? จะต่างกัน ดังนั้นต้องระวังสับสนและใช้ผิด

งานหลักๆของกล็อบก็คือใช้จัดการกับชื่อไฟล์ แต่เรกูลาร์เอ็กซ์เพรชชันถูกใช้งานกว้างขวางกว่ามาก

สำหรับงานค้นหาที่ไม่ซับซ้อนใช้กล็อบได้ก็ใช้กล็อบจะดูง่ายกว่า



อ้างอิง


-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> shell

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

目次

日本による名言集
モジュール
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
機械学習
-- ニューラル
     ネットワーク
javascript
モンゴル語
言語学
maya
確率論
日本での日記
中国での日記
-- 北京での日記
-- 香港での日記
-- 澳門での日記
台灣での日記
北欧での日記
他の国での日記
qiita
その他の記事

記事の類別



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  記事を検索

  おすすめの記事

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ

ไทย

日本語

中文