विशिष्ट एक्सटेंशन वाली सभी फ़ाइलों को gzip करें


11

मैं ubuntu कि फ़ाइल एक्सटेंशन .css, .html या .js पर सभी फ़ाइलों को gzip करने का प्रयास कर रहा हूं। एक शीर्ष निर्देशिका और सभी उपनिर्देशिकाओं में। मैं मूल फाइलें रखना चाहता हूं और .gz फाइल को अधिलेखित कर देता हूं, अगर पहले से मौजूद है।

इसलिए जब मेरे पास n फाइलें हैं, तो मैं इन n फाइलों को रखना चाहता हूं और अतिरिक्त n संग्रह फाइलें बनाना चाहता हूं। सिर्फ एक ही नहीं।

मेरी कोशिश एक स्क्रिप्ट चलाने की थी जो इस तरह दिखती है:

gzip -rkf *.css
gzip -rkf *.html
... one line for each file extension

पहला: मुझे उस स्क्रिप्ट में एक-एक लाइन की जरूरत है, जिसे मैं प्रत्येक फ़ाइल एक्सटेंशन के लिए चाहता हूँ जिसे मैं gzip करना चाहता हूँ। यह ठीक है, लेकिन मैं एक बेहतर तरीका खोजने की उम्मीद करता हूं

दूसरा और अधिक महत्वपूर्ण: यह काम नहीं करता है। हालांकि -r को काम करना चाहिए, उपनिर्देशिका अपरिवर्तित हैं। Gzip फ़ाइल केवल शीर्ष निर्देशिका में बनाई गई है।

मुझे यहां क्या समझ नहीं आ रहा है?

Btw: निम्नलिखित क्रिया उत्पादन में एक बग है, है ना? -K और -v विकल्प का उपयोग करते समय

-k, --keep        keep (don't delete) input files
-v, --verbose     verbose mode

वर्बोज़ आउटपुट कहता है कि यह फ़ाइल को बदल देता है, हालाँकि "प्रतिस्थापित" का अर्थ है कि मूल फ़ाइल को प्रतिस्थापित करने के बाद मौजूद नहीं है। वैसे भी, यह केवल उत्पादन की बात है।

$ ls
  index.html      subdir1  testfile      testfile.css.gz
  javaclass.java  subdir2  testfile.css
$ gzip -fkv *.css
  testfile.css:   6.6% -- replaced with testfile.css.gz
$ ls
  index.html      subdir1  testfile      testfile.css.gz
  javaclass.java  subdir2  testfile.css

1
-rडिजाइन के अनुसार काम करता है। से आदमी gzip : सफर निर्देशिका संरचना रिकर्सिवली। यदि कमांड लाइन पर निर्दिष्ट फ़ाइल नामों में से कोई भी निर्देशिका है , तो gzip निर्देशिका में उतरेगा और वहां मिलने वाली सभी फ़ाइलों को संपीड़ित करेगा (या गनज़िप के मामले में उन्हें हटा देगा)। (जोर मेरा)
डेनिस

ठीक है। So -r XYZ.css नाम से एक निर्देशिका दर्ज करेगा। फिर पुनरावृत्ति को डिज़ाइन नहीं किया गया जैसा कि मुझे उम्मीद थी।
सादिक

जवाबों:


7

आप ऐसा कर सकते हैं कि हर फाइल खोजने के लिए एक लूप के साथ इसे संपीड़ित करें:

for i in `find | grep -E "\.css$|\.html$"`; do gzip "$i" ; done

धन्यवाद! हालांकि -rविकल्प काम नहीं करता है, -kऔर -fकाम कर रहा है, इसलिए मैं उन्हें इस तरह से उपयोग कर सकता हूं: मैं के लिए find | grep -E "\.css$|\.html$"; gzip -vkf "$ i" करें; किया `
सादिक

@ सादिक: सावधान! यदि किसी फ़ाइल के नाम में कोई स्थान है तो यह दृष्टिकोण काम नहीं करेगा।
डेनिस

आप समझा सकते हैं कि क्यों नहीं?
सादिक

1
@ सादिक: `...`एक स्ट्रिंग प्रदान करता है, सूची नहीं। forआंतरिक क्षेत्र विभाजक ( $IFS) का उपयोग करता है यह तय करने के लिए कि स्ट्रिंग को कहाँ विभाजित किया जाना चाहिए। डिफ़ॉल्ट रूप से, यह लाइनफीड्स, टैब और स्पेस में विभाजित होता है, इसलिए यदि आपके पास एक फाइल है new style.css, जिसे कमांड कहा जाता है gzip newऔर gzip style.cssनिष्पादित किया जाएगा।
डेनिस

1
@ सादिक, डेनिस सही है, जल्दी वर्कअराउंड के रूप में आप लूप export IFS=$'\n'से ठीक पहले दौड़ सकते हैं for
14

14

मै इस्तेमाल करूंगा

find /path/to/dir \( -name '*.css' -o -name '*.html' \) -exec gzip --verbose --keep {} \;

बदलें nameकरने के लिए inameआप एक्सटेंशन से मेल करने के लिए केस-insensitively चाहते हैं (यानी शामिल .CSSऔर / या .HTMLएक्सटेंशन)। /path/to/dirयदि आप वर्तमान निर्देशिका से पुनरावर्ती खोज प्रारंभ करना चाहते हैं, तो आप इसे छोड़ सकते हैं ।


2
उन लोगों के लिए जो --keepस्विच के बारे में सोच रहे होंगे , हाँ, यह मूल फ़ाइलों को बनाए रखने का कारण बनता है। यदि आप चाहते हैं कि उन्हें एक बार gzipped हटा दिया जाए तो इसे छोड़ दें।
बेन जॉनसन

4

फ़ाइलों की सूची प्राप्त करने के लिए:

find -type f | grep -P '\.js|\.html|\.css'

और उन सभी फाइलों को gzip करने के लिए:

find -type f | grep -P '\.js|\.html|\.css' | tar cvzf archive.gz -T -

क्या यह फाइलों tarकी सूची को आउटपुट के रूप में findनहीं देगा, बल्कि फाइलों की खुद से?
जोस

मैंने अपने प्रश्न को यह स्पष्ट करने के लिए संपादित किया कि मुझे प्रत्येक css, html या js फ़ाइल के लिए एक संग्रह फ़ाइल चाहिए।
सादिक

2
-Tविकल्प के साथ @Jos tarफ़ाइलनाम के रूप में इनपुट को संसाधित करता है।
अराजकता

@ अचोस आह, शुक्रिया। मैंने आज कुछ सीखा।
जोस

2

मैंने स्टीलड्राइवर के उत्तर का उपयोग किया , लेकिन मैं इसे --bestऔर --forceविकल्पों के साथ पूरा करना पसंद करता हूं ।

cdकिसी भी फ़ोल्डर में और इस कोड को टाइप करें। आपकी सभी मिलान फ़ाइलें gzipped होंगी।

find . \( -name '*.css' -o -name '*.js' \) -exec gzip --verbose --keep --best --force {} \;
  • --bestसबसे अच्छा संपीड़न अनुपात के लिए उपयोग करें ।
  • --forceयदि कोई gzipped फ़ाइल है, तो बिना पूछे ओवरराइटिंग के लिए उपयोग करें ।

1

आप ग्लोबस्टार का उपयोग कर सकते हैं।

साथ globstarखोल विकल्प सक्षम, आप सभी की जरूरत है gzip -vk **/*.{css,html}

बैश शेल में एक globstarविकल्प होता है जिससे आप पुनरावर्ती ग्लब्स को लिख सकते हैं **shopt -s globstarसक्षम बनाता है। लेकिन आप ऐसा नहीं करना चाह सकते हैं कि बाद में आपके द्वारा चलाए जाने वाले अन्य आदेशों के लिए, इसलिए आप इसे और अपने gzip आदेश को इसके बजाय उप- भाग में चला सकते हैं ।

यह आदेश gzipसभी एस .cssऔर .htmlकिसी भी उसकी उप-की वर्तमान निर्देशिका में फ़ाइलों, के किसी भी उनके उपनिर्देशिका, आदि, मूल फ़ाइलें (रखते हुए -k) और आप इसे (क्या कर रही है कह -v):

(shopt -s globstar; gzip -vk **/*.{css,html})

यदि आप फ़ाइल नाम मामले-असंवेदनशील से मेल खाना चाहते हैं, तो कुछ या सभी अक्षरों के साथ उन एक्सटेंशन को शामिल किया गया है, तो आप nocaseglobशेल विकल्प को भी सक्षम कर सकते हैं :

(shopt -s globstar nocaseglob; gzip -vk **/*.{css,html})

;दो आदेशों को अलग करता है, और बाहरी ( )कारण उन्हें एक उपधारा में चलाया जाता है। किसी सब-शेल में शेल विकल्प सेट करने से कॉलिंग शेल में सेट होने का कारण नहीं बनता है। यदि आप सक्षम करना चाहते हैं globstarतो आप दौड़ सकते हैं shopt -s globstar; तो आप बस कमांड चला सकते हैं:

gzip -vk **/*.{css,html}

आप के globstarसाथ अक्षम कर सकते हैं shopt -u globstar। यदि आप वर्तमान में इसके साथ सक्षम हैं, तो आप देख सकते हैं shopt globstar

यह काम किस प्रकार करता है

यह gzipकमांड कैसे काम करता है इसकी कुंजी यह है कि शेल इस पर विस्तार करता है कि डायरेक्टरी पदानुक्रम में प्रत्येक फाइल की एक सूची का मिलान नाम के साथ करने के लिए, फिर इनमें से प्रत्येक फाइलनाम को तर्क के रूप में पास करता है gzip

  • ब्रेस विस्तार में बदल जाता **/*.{css,html}है **/*.css **/*.html
  • फिर ग्लोबिंग उन दो पैटर्नों को मौजूदा डायरेक्टरी के तहत एक्सेस की जाने वाली फाइलों के नाम में विस्तारित करता है ( जिनकी **वजह से 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, जैसा कि स्टीलड्राइवर वर्णन करता है (साथ {} \;) या जैसा कि मैं नीचे (साथ {} +) का वर्णन करता हूं ।

आप कार्रवाई के findसाथ -execऔर +दक्षता के लिए उपयोग कर सकते हैं ।

gzipआदेश का समर्थन करता है दिया जा रहा से अधिक फ़ाइलों के नाम संकुचित करने की। लेकिन यह findकमांड, हालांकि यह अच्छी तरह से काम करता है और तब तक धीमा नहीं होगा जब तक कि आपके पास कई फाइलें न हों, प्रत्येक फाइल के gzipलिए एक बार कमांड चलाता है :

find . \( -name \*.css -o -name \*.html \) -exec gzip -vk {} \;

यह काम करता है, और आप निश्चित रूप से इसका उपयोग कर सकते हैं। ( .वर्तमान निर्देशिका से खोज। इसके अलावा, यह वास्तव में स्टीलड्राइवर के बहुत अच्छे उत्तर में कमांड लिखने का एक अलग तरीका है ; आप जो भी पसंद करते हैं, उसका उपयोग कर सकते हैं।)

तुम भी findकई फाइलनामों को पास कर सकते हैं gzipऔर इसे केवल आवश्यकतानुसार कई बार चला सकते हैं - जो लगभग हमेशा सिर्फ एक बार होता है। ऐसा करने के लिए, के बजाय का उपयोग करें+\;+तर्क के तुरंत बाद ही आना चाहिए {}। अतिरिक्त फ़ाइल नाम के साथ findप्रतिस्थापित करता है +, यदि कोई हो।

find . \( -name \*.css -o -name \*.html \) -exec gzip -vk {} +

+यहां तक ​​कि अगर कुछ ही मिलान वाली फाइलें हैं, तो भी इसका उपयोग करना ठीक है , और जब उनमें से कई हैं, तो यह gzipप्रत्येक फ़ाइल के लिए एक अलग आह्वान होने की तुलना में अधिक तेज़ हो सकता है ।

जैसा कि स्टीलड्राइवर का उल्लेख है , आप मैच फाइलों के -inameबजाय उपयोग कर सकते हैं, -nameजिनका नाम पसंद है .cssया .htmlअलग-अलग पूंजीकरण के साथ। सक्षम करने के लिए इस मेल खाती nocaseglobमें globstarआधारित विधि ऊपर वर्णित है।

अंत में, आपके पास संभवत: कोई मेल खाने वाली फ़ाइल या निर्देशिका नहीं है जो इसके साथ शुरू होती है .। लेकिन अगर आप करते हैं, तो findस्वचालित रूप से उन्हें शामिल करता है। यदि आप उन्हें बाहर करना चाहते हैं (जैसा कि बंद globstarहोने पर ऊपर बताई गई विधि के साथ होता dotglobहै), आप कर सकते हैं :

find . -not -path '*/.*' \( -name \*.css -o -name \*.html \) -exec gzip -vk {} +

globstarआधारित तरीका ऊपर वर्णित लिखने के लिए आसान है, खासकर यदि आप को छोड़कर निर्देशिका और फ़ाइलों के साथ शुरू कर रहे हैं ., के बाद से है कि डिफ़ॉल्ट है।

क्या नहीं करना है ...

रास्ते के विभाजक /और अशक्त चरित्र को छोड़कर किसी भी वर्ण में फिल्नाम शामिल हो सकते हैं । कई तकनीकें जो अजीब फ़ाइलनामों पर टूटती हैं, मौजूद हैं, और वे आमतौर पर उन तकनीकों की तुलना में अधिक जटिल हैं जो हमेशा काम करती हैं। इसलिए मैं सुझाव देता हूं कि जब आप जानते हैं (या आपको लगता है कि आप जानते हैं) तब भी उनसे बचने की सलाह देते हैं। और निश्चित रूप से आपको उनका उपयोग नहीं करना चाहिए यदि आपके पास वर्णों के साथ फ़ाइलनाम हो सकते हैं जो विशेष रूप से रिक्त स्थान सहित इलाज किया जा सकता है।

findकिसी अन्य कमांड के आउटपुट को सुरक्षित रूप से पाइप करना संभव है जो इसे प्रोसेस करता है यदि आप इसका उपयोग करते हैं -print0या इसी तरह की कार्रवाई के कारण इसे एक न्यूलाइन के बजाय रास्तों के बीच एक अशक्त चरित्र डालते हैं , और अन्यथा नहीं। फ़ाइल नाम में नई सीमाएँ हो सकती हैं (हालांकि मैं आपको जानबूझकर उनके साथ नामकरण करने से हतोत्साहित करता हूँ)। कार्रवाई के findसाथ एक कमांड -print- जिसमें बिना किसी स्पष्ट कार्रवाई के कमांड शामिल हैं, तब -printसे डिफ़ॉल्ट है - आउटपुट का उत्पादन नहीं करता है जिसे सुरक्षित रूप से पाइप किया जा सकता है या अन्यथा किसी अन्य कमांड को प्रदान किया जा सकता है जो फ़ाइलों पर कार्रवाई करता है।

कार्रवाई के findसाथ उत्पादन का उत्पादन -print0सुरक्षित रूप से किया जा सकता है xargs -0( -0झंडा xargsअशक्त इनपुट की अपेक्षा करता है)।


0

फ़ोल्डर में सभी फ़ाइलों को ज़िप करने के लिए / सबफ़ोल्डर पुनरावर्ती रूप से:

gzip -r `find . -type f -name "*.html"` 

खोलने के लिए:

gunzip -r `find . -type f -name "*.gz"` 

यह कमांड प्रतिस्थापन आधारित विधि अक्सर टूट जाएगी, और काफी बुरी तरह से। समस्या यह है कि रिक्त स्थान या अन्य व्हाट्सएप वाले फ़ाइलनामों को विभाजित किया जाएगा और कई फ़ाइलनामों के रूप में माना जाएगा। (ये कमांड ` `सिंटैक्स का उपयोग करते हुए लिखे गए हैं , लेकिन सिंटैक्स का उपयोग करते समय समस्या पूरी तरह से लागू होती है $( )।)
एलियाह कगन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.