φυβλαςのβλογ
phyblas的博客



การใช้ glob เพื่อค้นหาไฟล์ที่ต้องการใน python
เขียนเมื่อ 2019/01/10 14:06
แก้ไขล่าสุด 2024/02/22 10:51
ปกติเวลาค้นชื่อไฟล์ในเชลยูนิกซ์จะนิยมเขียนแสดงในรูปแบบกล็อบ ดังที่ได้เขียนถึงไว้แล้วในบทความที่แล้ว https://phyblas.hinaboshi.com/20190109

ส่วนในภาษาไพธอนเองถ้าต้องการค้นชื่อไฟล์ด้วยกล็อบก็มีมอดูลชื่อ glob สามารถใช้งานได้สะดวก

ในบทความนี้จะแนะนำวิธีการใช้กล็อบในไพธอน ส่วนรายละเอียดวิธีการเขียนกล็อบสามารถเข้าไปอ่านในบทความที่แล้ว



glob.glob

ฟังก์ชัน glob.glob (ชื่อฟังก์ชันเหมือนกับชื่อมอดูล ระวังสับสน) เป็นคำสั่งพื้นฐานที่ใช้งานบ่อยสุดใน glob การใช้งานง่ายๆตรงไปตรงมาเลยคือ

ตัวอย่างการใช้ สมมุติว่าในโฟลเดอร์ที่อยู่มีไฟล์ชื่อ a.txt bb.txt ccc.txt dddd.csv
from glob import glob
print(glob('*.txt')) # ได้ ['ccc.txt', 'bb.txt', 'a.txt']
ผลที่ได้จะเป็นลิสต์ของชื่อไฟล์ทั้งหมดที่เข้าข่าย เพียงแต่ว่าผลที่ได้มักจะไม่ได้เรียงกันตามลำดับ อะไรจะขึ้นก่อนนั้นไม่อาจรู้ได้ หากต้องการให้เรียงตามชื่อควรใช้ sorted ช่วยจะดีกว่า
print(sorted(glob('*.txt'))) # ได้ ['a.txt', 'bb.txt', 'ccc.txt']

นอกจากนี้ถ้าต้องการให้เรียงตามขนาดไฟล์หรือเรียงตามเวลาที่แก้ไขไฟล์ก็อาจใช้แบบนี้ได้
import os
sorted(glob('*.txt'),key=os.path.getsize) # เรียงตามขนาดไฟล์
sorted(glob('*.txt'),key=os.path.getmtime) # เรียงตามเวลาที่แก้ไขไฟล์


glob.iglob

คำสั่ง glob.glob จะคืนค่าเป็นลิสต์ ซึ่งรายชื่อไฟล์ทั้งหมดจะถูกนำมาแสดงหรือเก็บไว้ในตัวแปรโดยทันที

แต่ในกรณีที่ต้องการนำมาวนด้วย for เพื่อเอาชื่อไฟล์มาใช้งานทีละชื่ออาจเลือกใช้คำสั่ง glob.iglob ได้

glob.iglob เหมือนกับ glob.glob แต่ต่างกันตรงที่ผลการค้นหาที่ได้จะเป็นเจเนอเรเตอร์ที่จะให้ค่าชื่อไฟล์ออกมาเมื่อถูกเรียกใช้ ไม่ได้ให้เป็นลิสต์ทันที
from glob import iglob
print(iglob('*.txt')) # ได้

ตัวอย่างการใช้ เช่นเอามาเข้าใน for เพื่อทำอะไรกับไฟล์ทีละไฟล์ได้ เช่นถ้าจะค้นหาไฟล์ทุกไฟล์เพื่อมาเปิดแล้วแสดงเนื้อหาทั้งหมดก็ทำแบบนี้ได้ เป็นต้น
for g in sorted(iglob('*.txt')):
   f = open(g)
   print(f.read())
   f.close()

glob.iglob จะไปค้นหาไฟล์ตอนที่มันถูกเรียกใช้ใน for นั่นหมายความว่าต่อให้ใช้ glob.iglob เพื่อสร้างตัวเจเนอเรเตอร์ไว้ก่อน ถ้าระหว่างนั้นไฟล์ในนั้นมีการเปลี่ยนแปลง ผลที่ได้ออกมาก็จะเป็นไปตามหลังจากการเปลี่ยนแปลง

อีกอย่างคือเนื่องจาก glob.iglob เป็นเจเนอเรเตอร์จึงถูกใช้วนใน for ได้แค่ครั้งเดียว นำมาใช้ซ้ำไม่ได้ถ้าไม่สร้างใหม่

รายละเอียดเพิ่มเติมเกี่ยวกับเจเนอเรเตอร์ อ่านได้ใน https://phyblas.hinaboshi.com/tsuchinoko26



glob.glob1

ฟังก์ชัน glob.glob1 จะคล้ายกับ glob.glob แต่ต่างกันตรงที่จะแยกโฟลเดอร์หลักกับไฟล์ที่ต้องการค้นออกจากกัน

เช่น ๒
from glob import glob,glob1
glob1('fg/','*') # ได้ ['ac.txt', 'ba.txt']

ถ้าใช้ glob จะเขียนแบบนี้
glob('fg/*') # ได้ ['fg/ac.txt', 'fg/ba.txt']

ผลที่ได้จะค้นเจอไฟล์เดียวกัน แต่ใช้ glob1 แล้วจะไม่มีชื่อโฟลเดอร์ติดมาด้วย ดังนั้นอาจสะดวกกว่าถ้าต้องการแค่ชื่อไฟล์อย่างเดียว



ถ้าเข้าใจความแตกต่างระหว่าง glob, iglob และ glob1 ก็สามารถแยกใช้ตามความเหมาะสมได้





fnmatch.fnmatch หรือ glob.fnmatch.fnmatch

ฟังก์ชัน fnmatch.fnmatch ในมอดูล fnmatch (ชื่อฟังก์ชันเหมือนกับชื่อมอดูลอีกแล้ว) ใช้สำหรับแค่ดูว่าชื่อไฟล์เข้าข่ายตามรูปแบบกล็อบที่กำหนดหรือไม่

ตัวอย่างการใช้
from fnmatch import fnmatch
print(fnmatch('a.py','*.py')) # ได้ True
print(fnmatch('a.py','*.txt')) # ได้ False

ที่จริงแล้วคำสั่ง glob ในไพธอนคือการเรียก os.listdir ซึ่งเป็นคำสั่งสำหรับไล่รายชื่อไฟล์ทั้งหมดในโฟลเดอร์ แล้วจากนั้นก็นำชื่อไฟล์มาคัดกรองด้วย fnmatch อีกทีนั่นเอง

ดังนั้น glob('*.txt') จะเท่ากับ
[g for g in os.listdir('./') if (fnmatch(g,'*.txt'))]

มอดูล fnmatch นี้มีการเรียกใช้โดย glob จึงถูกทำให้สามารถเข้าถึงผ่านมอดูล glob ได้ด้วย นั่นคือ fnmatch เท่ากับ glob.fnmatch
import glob,fnmatch
print(glob.fnmatch is fnmatch) # ได้ True


อ้างอิง


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

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

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

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python

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

目录

从日本来的名言
模块
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
机器学习
-- 神经网络
javascript
蒙古语
语言学
maya
概率论
与日本相关的日记
与中国相关的日记
-- 与北京相关的日记
-- 与香港相关的日记
-- 与澳门相关的日记
与台湾相关的日记
与北欧相关的日记
与其他国家相关的日记
qiita
其他日志

按类别分日志



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

  查看日志

  推荐日志

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