Glob Pattern Tester: เช็ก glob pattern ให้แม่นก่อนมัน match ไฟล์ผิด
ทดสอบ glob และ minimatch pattern กับรายชื่อไฟล์จริง รองรับ include/exclude, negation, brace expansion และ character class พร้อมไฮไลต์ผล match ทันที ฟรีและทำงานปลายทางในเบราว์เซอร์
Table of Contents
Glob Pattern Tester: เช็ก glob pattern ให้แม่นก่อนมัน match ไฟล์ผิด
Glob pattern คือตัวกำหนดว่าไฟล์ไหนที่ .gitignore จะ ignore, path ไหนที่ CI จะเฝ้าดูและอัปโหลด, ซอร์สไหนที่ TypeScript จะคอมไพล์ผ่าน include ใน tsconfig และไฟล์ไหนที่ lint config จะสแกน — แต่แทบไม่มีใครได้เรียน syntax นี้อย่างจริงจังเลย ปัญหาคือเครื่องมือแต่ละตัวตีความ glob ไม่เหมือนกัน: ** ที่ไล่ลง subdirectory ได้ใน engine หนึ่งอาจทำงานแบบอนุรักษ์นิยมในอีก engine หนึ่ง และ negation ที่เวิร์กใน Git กลับพังใน backup script Glob Pattern Tester ถูกสร้างมาเพื่อปิดช่องว่างนี้: วาง pattern และรายชื่อไฟล์จริงลงไป แล้วดูให้ชัดว่าไฟล์ไหน match บ้าง ก่อนที่ rule นั้นจะถูกเขียนลง config
Glob พลาดแบบเงียบ ๆ ค่าที่ต้องจ่ายเลยหนัก: pattern ที่เพี้ยนไปหนึ่งตัวอักษรอาจซ่อนไฟล์ที่คุณตั้งใจเก็บไว้ หรือกวาดเอาไฟล์ที่มากเกินตั้งใจเข้ามา — ทั้ง folder dependency ที่ห้อยไปกับ artifact ใน CI หรือ secret ที่ถูก commit เพราะ ignore rule ไม่เคยทำงาน
Glob Pattern Tester ทำให้ feedback loop ของคุณเร็วและปลอดภัย รองรับ include/exclude rule, negation ด้วย !, brace expansion แบบ {a,b} และ character class อย่าง [a-z] พร้อมติดป้ายทุก path ทันทีว่า match, ถูก exclude หรือไม่ match ขณะที่คุณพิมพ์ ทุกอย่างทำงาน 100 percent client-side ในเบราว์เซอร์และใช้ offline ต่อได้
ทำไมต้องใช้ Glob Tester?
- เห็นผลทันที ไม่ต้องเดามั่ว — เลิกแก้ .gitignore แล้วสั่ง git status ซ้ำ ๆ เพื่อดูว่าอะไรเปลี่ยน ผลลัพธ์อัปเดตตาม pattern ทันที จากเดิมที่ต้องเดาแล้วเช็กหลายนาที เหลือแค่ชำเลืองดูไม่กี่วินาที
- เห็น include และ exclude พร้อมกัน — ทั้งสองชุด rule ถูกประเมินเป็นคู่ ทำให้เห็นทันทีว่า exclude ตัวไหนลบทับ include ที่ตั้งใจไว้
- จับความต่างระหว่างเครื่องมือก่อนมันกัด — pattern หน้าตาเหมือนกันอาจทำงานต่างกันบน minimatch, Git, shell และ build tool การทดสอบกับรายชื่อไฟล์จริงเผยความต่างเหล่านี้ก่อนคุณ commit
- ปลอดภัยกับโครงสร้าง repository ภายใน — ทุกการประเมินเกิดขึ้นบนเครื่องคุณ โครงสร้าง directory ภายในองค์กรไม่หลุดออกจากเครื่องแน่นอน
- เรียน syntax จากตัวอย่าง — สลับ * เป็น **, เติม !, ขยาย [a-c] เป็น [a-z] แล้วดูว่าไฟล์ไหนเปลี่ยนสถานะ เป็นวิธีที่สร้าง mental model ที่ถูกต้องได้ไวที่สุด
ฟีเจอร์หลัก
| ฟีเจอร์ | ทำอะไร | ทำไมจึงสำคัญ |
|---|---|---|
| Include pattern | Match path กับ glob สไตล์ minimatch | ครึ่งบวกของทุกชุด rule |
| Exclusion และ negation | Pattern ที่ขึ้นต้นด้วย ! ลบผลที่ match ก่อนหน้า | แยกข้อยกเว้นออกจาก rule กว้าง ๆ |
| Brace expansion | {js,ts} ขยายเป็นทางเลือกหลายแบบก่อน match | หนึ่งบรรทัดแทนหนึ่ง rule ต่อนามสกุล |
| Character class | [abc] และ range match หนึ่งตัวอักษรจากเซต | แม่นระดับตัวอักษรโดยไม่ต้องไล่ใส่ทีละตัว |
| ไฮไลต์ผลทันที | ทุก path ถูกติดป้ายว่า match, excluded หรือไม่ match แบบสด ๆ | เห็นนัยของการแก้แต่ละครั้งทันที |
| 100 percent client-side | ประเมินทั้งหมดในเบราว์เซอร์ | path ส่วนตัวอยู่กับเครื่อง ใช้ offline ได้ |
- ใส่ comment ได้ — บรรทัดที่ขึ้นต้นด้วย # จะถูกข้าม วาง rule set ที่มีคำอธิบายประกอบลง pull request ได้เลย
- คัดลอกเฉพาะที่ match — คลิกเดียวได้รายชื่อไฟล์ที่ match สุดท้าย ไว้ใช้กับ script หรือ CI config
วิธีใช้งาน
- เปิดเครื่องมือ — เข้า Glob Pattern Tester ด้วยเบราว์เซอร์สมัยใหม่ตัวไหนก็ได้ ไม่ต้องติดตั้งอะไร
- วางรายชื่อไฟล์จริง — ใช้ผลลัพธ์จาก git ls-files, directory listing หรือ build log path จริงชนะ path ที่เดาขึ้นมา เพราะ path จริงมีความลึกของโครงสร้างที่ทำ pattern หลวม ๆ พัง
- เขียน include pattern — ใส่หนึ่ง glob ต่อหนึ่งบรรทัด เช่น src/**/*.test.ts ผลลัพธ์อัปเดตขณะพิมพ์
- เติม exclusion ด้วย ! — นำหน้า pattern ด้วย ! เช่น !src/generated/** แล้วดูแถวที่กระทบเปลี่ยนจาก matched เป็น excluded
- ปรับจนเข้าที่แล้วคัดลอก — ปรับจนชุดไฟล์ที่ match ตรงใจ แล้วคัดลอก path หรือ rule set ไปใส่ config
*, ** และ brace
Syntax ของ glob เล็กนิดเดียว แต่ตัวอักษรสองตัวอาจแยกกันระหว่างหกไฟล์กับหกพันไฟล์
ดาวเดียว: จำกัดหนึ่ง segment — * match ตัวอักษรได้ทุกตัวยกเว้นตัวคั่น path ดังนั้น src/*.js match src/index.js แต่ไม่ match src/lib/util.js — มันไม่มีวันข้าม slash
ดาวคู่: ลึกได้ทุกระดับ — segment ** match directory ได้ตั้งแต่ศูนย์ชั้นขึ้นไป src/**/*.js จึงไปถึง src/lib/deep/format.js ด้วย แต่ต้องเป็น segment เต็มเท่านั้น — src** เป็นสัตว์ต่างสายพันธุ์ที่บาง engine ปฏิเสธ
เครื่องหมายคำถาม: หนึ่งตัวอักษรพอดี — file?.ts match file1.ts แต่ไม่ match file10.ts และไม่ match ตัวคั่นเช่นกัน
Negation: ลำดับคือผู้ตัดสิน — pattern ที่ขึ้นต้นด้วย ! จะลบผลที่ rule ก่อนหน้า match ไว้ ใน engine สไตล์ gitignore บรรทัดสุดท้ายที่ match ชนะเสมอ คู่ลำดับนี้จึงเลือกทุกอย่างก่อน แล้วค่อยเอา node_modules ออก:
** !node_modules/**
สลับสองบรรทัดเมื่อไร negation ก็ไร้ความหมาย และมีเรื่อง Git ที่ควรจำ: Git จะไม่ลงไปใน directory ที่ถูก exclude อยู่แล้ว คุณต้อง re-include ตัว directory ก่อนจึงจะดึงไฟล์ข้างในกลับมาได้
Brace คูณทางเลือก — src/**/*.{js,ts} ขยายเป็นสอง pattern ก่อนเริ่ม match แต่ละบรรทัดที่ประหยัดได้ คือโอกาสพิมพ์ path ผิดที่ลดลงหนึ่งครั้ง
Character class ล็กตัวอักษร — [abc] match หนึ่งตัวในเซต, [a-z0-9] เพิ่ม range และ minimatch เขียน class แบบกลับความหมายเป็น [!abc] ไม่ใช่ [^abc] แบบ regex ที่หลายคนคุ้นเคย class ช่วยสกัดดาวที่กินเกิน: report-[0-9][0-9].csv match เฉพาะเลขสองหลัก
คิดให้เป็นคู่ include/exclude — include กว้าง ๆ ตามด้วย exclusion แบบผ่าตัดเฉพาะจุด แล้วตรวจสอบเป็นคู่ คือ workflow ที่เชื่อถือได้ ตัวอย่าง "match ทุกอย่างใน src ยกเว้น generated code":
src/** !src/generated/**
| Path | ผลลัพธ์ |
|---|---|
| src/index.ts | matched |
| src/lib/util.ts | matched |
| src/generated/api.ts | โดน negation ตัดออก |
| dist/bundle.js | ไม่เคย match |
งานกลับด้าน — ignore ทุกอย่างยกเว้น src — เป็นสำนวนของ Git: /* ignore ทุก entry ระดับบนสุด แล้ว !/src บรรทัดถัดมาดึง directory กลับมา ลำดับแบบนี้คือหัวใจ
การใช้งานจริง
เขียนกฎ .gitignore
ความพลาดเงียบ ๆ เจ็บที่สุดที่นี่ ก่อน commit rule ให้วาง path ที่ git status แสดงพร้อม rule set ลงเครื่องมือ แล้วยืนยันว่าแต่ละ path ลงตระกร้าที่ตั้งใจ — โดยเฉพาะ negation ที่ต้องอยู่หลัง rule กว้างที่มันแก้
Pattern ใน tsconfig และ ESLint
include/exclude ของ TypeScript, ignores ของ ESLint และ .prettierignore ล้วนใช้ syntax กลิ่น glob แต่แต่ละ engine มีมุมต่างกันเรื่อง **, negation และการ match นามสกุลไฟล์ ตรวจกับโครงสร้างจริงของคุณก่อนวางลง config
Path ของ artifact และ cache ใน CI
segment เพี้ยนหนึ่งที่ ทั้ง folder ม้าโหดก็ห้อยตามมาเป็น artifact หรือไม่ก็ deploy ของไม่ครบ โดยเฉพาะ source map ที่ชอบรั่วผ่าน pattern กว้าง ๆ — ทดสอบกับ path จริงที่ workflow ผลิตออกมา
Script backup และ sync
อย่าง rsync ใช้ include/exclude filter แบบ first match wins — ลำดับตรงข้ามกับ Git ชุดที่ผ่านการตรวจกับ Git อาจเงียบ ๆ ข้าม directory ข้อมูลไป เช็กกับเครื่องมือก่อน แล้วค่อยคิดบัญชีความต่างของ engine ตอนแปลงไปใช้
แนวทางปฏิบัติที่ดี
- ทดสอบกับรายชื่อไฟล์จริง — path ที่เดาขึ้นมาซ่อนความลึกที่ทำ pattern พัง วางผล git ls-files แล้วให้เครื่องมือตัดสินของจริง
- ระวังความต่างของ engine — minimatch, Git, shell และ build tool เห็นต่างกันเรื่อง edge case ของ **, class แบบกลับความหมาย และลำดับการ match
- เลือกแคบเกินกว่าจะกว้างจนพลาด — pattern ที่บางครั้งหลุดยังน่ารำคาญแค่เรื่องเล็ก แต่ pattern ที่ match .env เงียบ ๆ คือ incident
- วาง negation ไว้ติด rule ที่มันแก้ — last-match-wins คือผู้ตัดสิน การโปรยข้อยกเว้นกระจายไปทั่วไฟล์ย่อมเชิญบั๊กเรื่องลำดับ
- ใส่ anchor อย่างตั้งใจ — รู้ให้ชัดว่า rule ใช้จาก root หรือทุกที่ (/dist กับ dist ใน Git ต่างกัน) และ slash ต่อท้ายจำกัดให้ match เฉพาะ directory หรือไม่
- เก็บ rule set ที่ผ่านการตรวจไว้ข้าง config — บันทึก pattern ที่ยืนยันแล้วไว้ใน comment หรือ pull request เพื่อให้คนถัดไปได้หลักฐาน ไม่ใช่การเดา
พร้อมเลิกเจอบั๊ก glob ใน production แล้วหรือยัง? เปิด Glob Pattern Tester วางผล git ls-files ของคุณ ลอง pattern ที่กำลังจะ commit แล้วยืนยันว่าทุก path ลงตรงจุดที่ตั้งใจ
เครื่องมือที่เกี่ยวข้องที่คุณอาจสนใจ:
- Regex Railroad Diagram Generator — เห็น regular expression เป็น syntax diagram แบบอินเทอร์แอกทีฟ
- .gitattributes Generator — คุม line ending, การ mark binary และ export-ignore ด้วยไฟล์ Git attributes
- URI Template Expander — ขยาย URI template ตาม RFC 6570 อย่าง /users/{id}{?fields} พร้อมตารางตัวแปรสด ๆ
Glob ทุกตัวคือคำสัญญาว่าไฟล์ไหนถูกนับ ทดสอบคำสัญญากับ path จริง แล้วส่ง rule set ที่คุณรับผิดชอบได้ ไม่ใช่แค่เดาว่ามันน่าจะถูก
คำถามที่พบบ่อย
ถ: รายชื่อไฟล์หรือ pattern ของฉันถูกส่งขึ้นเซิร์ฟเวอร์ไหม?
ตอบ: ไม่ การ compile และ match เกิดขึ้นทั้งหมดในเบราว์เซอร์ของคุณ และเครื่องมือยังใช้ได้แบบ offline หลังโหลดครั้งแรก
**ถ: ความต่างจริง ๆ ระหว่าง * กับ ** คืออะไร?**
ตอบ: * ตัวเดียวไม่ข้าม slash จึงอยู่แค่ใน src เมื่อเขียน src/*.js ส่วน segment ** match directory ได้ทุกระดับความลึก src/**/*.js จึงไปถึง src/lib/deep/format.js ด้วย
ถ: ทำไม negation ของฉันเวิร์กที่นี่แต่ไม่เวิร์กใน .gitignore?
ตอบ: เรื่องลำดับ — บรรทัดสุดท้ายที่ match ชนะ ข้อยกเว้น ! ต้องอยู่หลัง rule กว้าง และ Git ไม่ลงไปใน directory ที่ถูก exclude แล้ว ต้อง re-include ตัว directory แม่ก่อน