คุณสามารถใช้ globstar
ด้วยตัวเลือกเปลือกเปิดใช้งานทั้งหมดที่คุณต้องการglobstargzip -vk **/*.{css,html}
ทุบตีเปลือกมีglobstarตัวเลือกที่ช่วยให้คุณเขียน recursive globs**กับ shopt -s globstarเปิดใช้งานมัน แต่คุณอาจไม่ต้องการทำเช่นนั้นสำหรับคำสั่งอื่น ๆ ที่คุณเรียกใช้ในภายหลังเพื่อให้คุณสามารถเรียกใช้และgzip คำสั่งของคุณในsubshellแทน
คำสั่งนี้gzipทุกอย่าง.cssและ.htmlไฟล์ในไดเรกทอรีปัจจุบันใด ๆ ของไดเรกทอรีย่อยใด ๆ ของพวกเขาไดเรกทอรีย่อย ฯลฯ , การเก็บรักษาไฟล์ต้นฉบับ ( -k) และบอกคุณว่ามันทำ ( -v):
(shopt -s globstar; gzip -vk **/*.{css,html})
หากคุณต้องการจับคู่ชื่อไฟล์แบบตรงตามตัวพิมพ์ใหญ่เพื่อให้ส่วนขยายเหล่านั้นรวมตัวอักษรบางส่วนหรือทั้งหมดเป็นตัวพิมพ์ใหญ่คุณสามารถเปิดใช้งานnocaseglobตัวเลือกเชลล์ได้:
(shopt -s globstar nocaseglob; gzip -vk **/*.{css,html})
;แยกคำสั่งสองคำสั่งและ( )สาเหตุด้านนอกทำให้คำสั่งเหล่านั้นถูกเรียกใช้ใน subshell การตั้งค่าตัวเลือกของเชลล์ใน subshell ไม่ได้ทำให้มันถูกตั้งค่าในการเรียกเชลล์ หากคุณไม่ต้องการเปิดใช้งานglobstarแล้วคุณสามารถเรียกใช้shopt -s globstar; จากนั้นคุณสามารถเรียกใช้คำสั่ง:
gzip -vk **/*.{css,html}
คุณสามารถปิดการใช้งานด้วยglobstar คุณสามารถตรวจสอบได้หากมีการเปิดใช้งานอยู่ด้วยshopt -u globstarshopt globstar
มันทำงานอย่างไร
กุญแจสำคัญในการวิธีนี้ทำงานคำสั่งว่าการขยายเปลือกดำเนินการเกี่ยวกับมันในการผลิตรายการของแต่ละไฟล์ในลำดับชั้นไดเรกทอรีที่มีชื่อตรงกันแล้วผ่านไปแต่ละชื่อไฟล์เหล่านี้เป็นข้อโต้แย้งgzipgzip
- การขยายตัวรั้งผลัดกันเข้าไป
**/*.{css,html}**/*.css **/*.html
- จากนั้นglobbingขยายทั้งสองรูปแบบเข้ามาในชื่อของไฟล์ที่สามารถเข้าถึงได้ภายใต้ไดเรกทอรีปัจจุบัน (
**เนื่องจากglobstar) ที่มีชื่อไฟล์ประกอบด้วยอะไร ( *) ตามด้วยคำต่อท้ายที่ระบุ ( .cssหรือ.htmlในกรณีนี้)
สิ่งนี้ไม่ตรงกับไฟล์ที่ชื่อขึ้นต้นด้วย.หรืออยู่ในไดเรกทอรีที่ตั้งชื่อด้วยวิธีนี้ คุณอาจไม่มีไฟล์ HTML และ CSS และคุณอาจไม่ต้องการรวมไฟล์เหล่านั้น แต่ถ้าคุณต้องการที่จะรวมพวกเขาคุณสามารถจับคู่พวกเขาอย่างชัดเจนขึ้นอยู่กับความต้องการของคุณ ตัวอย่างเช่นการเปลี่ยน**/*.{css,html}เป็น**/{,.}*.{css,html}ไฟล์ที่ขึ้นต้นด้วย.ในขณะที่ยังไม่ค้นหาในโฟลเดอร์ที่ทำ
หากคุณต้องการให้ทั้งไฟล์ที่ชื่อขึ้นต้นด้วย.และไฟล์ในไดเรกทอรีที่ชื่อขึ้นต้น.รวมอยู่นั้นจะมีวิธีที่สะอาดกว่าและง่ายกว่า: เปิดใช้งานdotglobตัวเลือกเชลล์
(shopt -s globstar dotglob; gzip -vk **/*.{css,html})
หรือถ้าคุณต้องการที่ตรงกันกรณีตายและการจับคู่ของชื่อไฟล์ที่ขึ้นต้นด้วย.:
(shopt -s globstar nocaseglob dotglob; gzip -vk **/*.{css,html})
เป็นไปได้แม้ว่าจะหายากมากสำหรับ**การขยายไปยังบางสิ่งที่ยาวเกินไป
หากคุณมีขนาดใหญ่จำนวนไฟล์ชื่อด้วยวิธีนี้แล้วนี้อาจล้มเหลวด้วยข้อผิดพลาดอธิบายว่าเปลือกไม่สามารถสร้างบรรทัดคำสั่งเพราะมันจะยาวเกินไป (ถึงแม้จะมีหลายพันไฟล์นี้มักจะไม่เป็นปัญหา.)
gzip จะไม่ถูกเรียกเลยดังนั้นคุณจะไม่ได้งานที่ทำไปแล้ว
หากข้อผิดพลาดนี้เกิดขึ้นหรือถ้าคุณกังวลเกี่ยวกับเรื่องนี้คุณสามารถใช้findกับ-execได้เช่นกันขณะที่steeldriver อธิบาย (ด้วย{} \;) หรือตามที่ฉันอธิบายด้านล่าง (กับ{} +)
คุณสามารถใช้findกับ-execแอ็คชั่นและ+เพื่อประสิทธิภาพ
gzipชื่อคำสั่งที่ได้รับการสนับสนุนจากหลายไฟล์ที่ถูกบีบอัด แต่findคำสั่งนี้แม้ว่ามันจะทำงานได้ดีและจะไม่ช้าถ้าคุณมีไฟล์จำนวนมากให้รันgzipคำสั่งหนึ่งครั้งสำหรับแต่ละ ไฟล์:
find . \( -name \*.css -o -name \*.html \) -exec gzip -vk {} \;
ใช้งานได้และคุณสามารถใช้งานได้อย่างแน่นอน ( .ค้นหาจากไดเรกทอรีปัจจุบันนอกจากนั้นมันเป็นวิธีที่แตกต่างกันเล็กน้อยในการเขียนคำสั่งในคำตอบที่ดีมากของ steeldriverคุณสามารถใช้รูปแบบใดก็ได้ที่คุณต้องการ)
นอกจากนี้คุณยังสามารถfindส่งผ่านชื่อไฟล์หลาย ๆ ไฟล์ไปยังgzipและเรียกใช้ได้หลายครั้งเท่าที่จำเป็นซึ่งเกือบจะแค่ครั้งเดียว จะทำอย่างไรที่จะใช้+\;แทน อาร์กิวเมนต์ควรมาหลัง+ แทนที่ด้วยชื่อไฟล์เพิ่มเติมถ้ามี{}find+
find . \( -name \*.css -o -name \*.html \) -exec gzip -vk {} +
เป็นการดีที่จะใช้+แม้ว่าจะมีไฟล์ที่ตรงกันเพียงไม่กี่ไฟล์เท่านั้นและเมื่อมีไฟล์จำนวนมากมันก็สามารถสังเกตได้เร็วกว่าการgzipเรียกใช้ไฟล์แยกต่างหากสำหรับแต่ละไฟล์
ในฐานะที่เป็นคนขับรถเหล็กที่กล่าวถึงคุณสามารถใช้-inameแทน-nameการจับคู่ไฟล์ที่มีชื่อเหมือน.cssหรือ.htmlด้วยตัวพิมพ์ใหญ่ที่แตกต่างกัน สิ่งนี้สอดคล้องกับการเปิดใช้งานnocaseglobในglobstarวิธี -based อธิบายไว้ข้างต้น
สุดท้ายคุณอาจไม่ได้ตรงกับไฟล์หรือไดเรกทอรีใด ๆ .ที่เริ่มต้นด้วย แต่ถ้าคุณfindรวมไว้โดยอัตโนมัติ หากคุณต้องการยกเว้นพวกเขา (เช่นเดียวกับที่เกิดขึ้นกับglobstarวิธีการตามรายละเอียดด้านบนเมื่อdotglobปิด) คุณสามารถ :
find . -not -path '*/.*' \( -name \*.css -o -name \*.html \) -exec gzip -vk {} +
globstarวิธีชั่อธิบายไว้ข้างต้นคือง่ายต่อการเขียนโดยเฉพาะอย่างยิ่งถ้าคุณไม่รวมไดเรกทอรีและไฟล์ที่ขึ้นต้นด้วย.ตั้งแต่ที่เริ่มต้น
อะไรไม่ได้ที่จะทำ ...
ชื่อไฟล์สามารถมีตัวอักษรใด ๆ ยกเว้นคั่นเส้นทาง/และอักขระ null มีเทคนิคมากมายที่ใช้ชื่อไฟล์แปลก ๆ และมักจะซับซ้อนกว่าเทคนิคที่ใช้งานได้ ดังนั้นฉันขอแนะนำให้หลีกเลี่ยงแม้ว่าคุณจะรู้ (หรือคิดว่าคุณรู้) พวกเขาก็โอเคในสถานการณ์เฉพาะของคุณ และแน่นอนคุณจะต้องไม่ใช้มันหากคุณมีชื่อไฟล์ที่มีตัวละครที่อาจได้รับการดูแลเป็นพิเศษรวมถึงช่องว่าง
เป็นไปได้ที่จะไพพ์เอาต์พุตอย่างปลอดภัยfindไปยังคำสั่งอื่นที่ประมวลผลหากคุณใช้-print0หรือการดำเนินการที่คล้ายกันเพื่อทำให้อักขระว่างระหว่างพา ธ แทนการขึ้นบรรทัดใหม่ไม่ใช่อย่างอื่น ชื่อไฟล์สามารถมีการขึ้นบรรทัดใหม่ (แม้ว่าฉันจะไม่สนับสนุนให้คุณตั้งชื่อไฟล์โดยเจตนา) findคำสั่งด้วย-printการกระทำ - รวมทั้งคำสั่งพบกับไม่มีการดำเนินการอย่างชัดเจนตั้งแต่นั้นมา-printเป็นค่าเริ่มต้น - ไม่ได้ผลิตออกที่สามารถได้อย่างปลอดภัยได้รับการประปาหรือให้กับคำสั่งอื่นอย่างอื่นที่มีประสิทธิภาพการดำเนินการในแฟ้ม
เอาต์พุตที่findสร้างขึ้นพร้อมกับ-print0แอ็คชันอาจถูกไพพ์อย่างปลอดภัยxargs -0( -0แฟล็กบอกxargsให้คาดหวังอินพุตที่คั่นด้วย null)
-rทำงานตามที่ออกแบบไว้ จากman gzip : เดินทางโครงสร้างไดเร็คทอรี่แบบเรียกซ้ำ หากชื่อไฟล์ใด ๆ ที่ระบุในบรรทัดคำสั่งเป็นไดเรกทอรี gzip จะลงไปในไดเรกทอรีและบีบอัดไฟล์ทั้งหมดที่พบมี (หรือขยายในกรณีของ gunzip) (เน้นที่เหมือง)