लोग यूनिक्स शेल सीखना चाहते हैं इसका एक सामान्य कारण बैच प्रोसेसिंग की शक्ति को अनलॉक करना है। यदि आप कई फाइलों पर कुछ क्रियाओं को करना चाहते हैं, तो ऐसा करने का एक तरीका उन फाइलों पर चलने वाली कमांड का निर्माण करना है। प्रोग्रामिंग शब्दावली में, इसे निष्पादन नियंत्रण, . कहा जाता है और इसके सबसे सामान्य उदाहरणों में से एक है के लिए लूप।
ए के लिए लूप एक नुस्खा है जो इस बात का विवरण देता है कि आप अपने कंप्यूटर से के लिए . कौन सी कार्रवाइयां करना चाहते हैं आपके द्वारा निर्दिष्ट प्रत्येक डेटा ऑब्जेक्ट (जैसे कोई फ़ाइल)।
लूप के लिए क्लासिक
कोशिश करने के लिए एक आसान लूप वह है जो फाइलों के संग्रह का विश्लेषण करता है। यह शायद अपने आप में एक उपयोगी लूप नहीं है, लेकिन यह अपने आप को साबित करने का एक सुरक्षित तरीका है कि आपके पास निर्देशिका में प्रत्येक फ़ाइल को व्यक्तिगत रूप से संभालने की क्षमता है। सबसे पहले, एक निर्देशिका बनाकर और उसमें कुछ फाइलों की कुछ प्रतियां रखकर एक सरल परीक्षण वातावरण बनाएं। शुरुआत में कोई भी फाइल काम करेगी, लेकिन बाद के उदाहरणों में ग्राफिक फाइलों (जैसे जेपीईजी, पीएनजी, या इसी तरह) की आवश्यकता होती है। आप फ़ाइल प्रबंधक या टर्मिनल का उपयोग करके फ़ोल्डर बना सकते हैं और उसमें फ़ाइलें कॉपी कर सकते हैं:
$ mkdir example
$ cp ~/Pictures/vacation/*.{png,jpg} example
निर्देशिका को अपने नए फ़ोल्डर में बदलें, फिर उसमें फाइलों को सूचीबद्ध करें ताकि यह पुष्टि हो सके कि आपका परीक्षण वातावरण वही है जिसकी आप अपेक्षा करते हैं:
$ cd example
$ ls -1
cat.jpg
design_maori.png
otago.jpg
waterfall.png
प्रत्येक फ़ाइल को लूप में अलग-अलग लूप करने का सिंटैक्स है:एक वैरिएबल बनाएं (f फ़ाइल के लिए, उदाहरण के लिए)। फिर उस डेटा सेट को परिभाषित करें जिसके माध्यम से आप चर को चक्रित करना चाहते हैं। इस मामले में, * . का उपयोग करके वर्तमान निर्देशिका में सभी फ़ाइलों के माध्यम से साइकिल चलाएं वाइल्डकार्ड वर्ण (* वाइल्डकार्ड सब कुछ से मेल खाता है ) फिर इस परिचयात्मक खंड को अर्धविराम से समाप्त करें (; )।
$ for f in * ;
अपनी पसंद के आधार पर, आप वापसी press को दबाना चुन सकते हैं यहां। शेल लूप को तब तक निष्पादित करने का प्रयास नहीं करेगा जब तक कि यह वाक्यात्मक रूप से पूर्ण न हो जाए।
इसके बाद, परिभाषित करें कि आप लूप के प्रत्येक पुनरावृत्ति के साथ क्या करना चाहते हैं। सरलता के लिए, फ़ाइल . का उपयोग करें प्रत्येक फ़ाइल के बारे में थोड़ा सा डेटा प्राप्त करने के लिए कमांड, जिसे f . द्वारा दर्शाया गया है चर (लेकिन एक $ . के साथ जोड़ा गया वर्तमान में जो कुछ भी वेरिएबल है उसके लिए वेरिएबल के मान को स्वैप करने के लिए शेल को बताने के लिए:
do file $f ;
क्लॉज को दूसरे सेमी-कोलन से खत्म करें और लूप को बंद करें:
done
वापसी दबाएं सब कुछ . के माध्यम से शेल साइकिल चलाना शुरू करने के लिए वर्तमान निर्देशिका में। के लिए लूप प्रत्येक फ़ाइल को एक-एक करके वेरिएबल f . को असाइन करता है और आपका आदेश चलाता है:
$ for f in * ; do
> file $f ;
> done
cat.jpg: JPEG image data, EXIF standard 2.2
design_maori.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced
otago.jpg: JPEG image data, EXIF standard 2.2
waterfall.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced
आप इसे इस तरह भी लिख सकते हैं:
$ for f in *; do file $f; done
cat.jpg: JPEG image data, EXIF standard 2.2
design_maori.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced
otago.jpg: JPEG image data, EXIF standard 2.2
waterfall.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced
दोनों बहु-पंक्ति और एकल-पंक्ति प्रारूप आपके शेल के लिए समान हैं और सटीक समान परिणाम देते हैं।
एक व्यावहारिक उदाहरण
यहां एक व्यावहारिक उदाहरण दिया गया है कि दैनिक कंप्यूटिंग के लिए लूप कैसे उपयोगी हो सकता है। मान लें कि आपके पास छुट्टियों की तस्वीरों का एक संग्रह है जिसे आप दोस्तों को भेजना चाहते हैं। आपकी फ़ोटो फ़ाइलें बहुत बड़ी हैं, जो उन्हें ईमेल करने के लिए बहुत बड़ी और आपकी फ़ोटो-साझाकरण सेवा पर अपलोड करने में असुविधाजनक बनाती हैं। आप अपनी फ़ोटो के छोटे वेब-संस्करण बनाना चाहते हैं, लेकिन आपके पास 100 फ़ोटो हैं और आप प्रत्येक फ़ोटो को एक-एक करके कम करने में समय नहीं लगाना चाहते हैं।
सबसे पहले, ImageMagick स्थापित करें Linux, BSD, या Mac पर अपने पैकेज मैनेजर का उपयोग करके कमांड करें। उदाहरण के लिए, फेडोरा और आरएचईएल पर:
$ sudo dnf install ImageMagick
उबंटू या डेबियन पर:
$ sudo apt install ImageMagick
बीएसडी पर, पोर्ट का उपयोग करें या पीकेजीएसआरसी। Mac पर, Homebrew या MacPorts का उपयोग करें।
एक बार जब आप ImageMagick स्थापित कर लेते हैं, तो आपके पास फ़ोटो पर काम करने के लिए नए आदेशों का एक सेट होता है।
आप जिन फ़ाइलों को बनाने जा रहे हैं उनके लिए एक गंतव्य निर्देशिका बनाएँ:
$ mkdir tmp
प्रत्येक फ़ोटो को उसके मूल आकार के 33% तक कम करने के लिए, इस लूप को आज़माएँ:
$ for f in * ; do convert $f -scale 33% tmp/$f ; done
फिर tmp . में देखें अपनी स्केल की गई तस्वीरों को देखने के लिए फ़ोल्डर।
आप लूप के भीतर कितनी भी कमांड का उपयोग कर सकते हैं, इसलिए यदि आपको फाइलों के एक बैच पर जटिल कार्य करने की आवश्यकता है, तो आप अपने पूरे वर्कफ़्लो को करें के बीच रख सकते हैं। और किया गया के लिए . के कथन फंदा। उदाहरण के लिए, मान लें कि आप प्रत्येक संसाधित फ़ोटो को सीधे अपने वेब होस्ट पर साझा फ़ोटो निर्देशिका में कॉपी करना चाहते हैं और फ़ोटो फ़ाइल को अपने स्थानीय सिस्टम से निकालना चाहते हैं:
$ for f in * ; do
convert $f -scale 33% tmp/$f
scp -i seth_web tmp/$f [email protected]:~/public_html
trash tmp/$f ;
done
के लिए . द्वारा संसाधित प्रत्येक फ़ाइल के लिए लूप, आपका कंप्यूटर स्वचालित रूप से तीन कमांड चलाता है। इसका मतलब है कि अगर आप इस तरह से सिर्फ 10 तस्वीरें प्रोसेस करते हैं, तो आप खुद को 30 कमांड सेव करते हैं और शायद कम से कम इतने मिनट।
अपने लूप को सीमित करना
एक लूप को हमेशा हर फाइल को देखने की जरूरत नहीं होती है। हो सकता है कि आप अपनी उदाहरण निर्देशिका में केवल JPEG फ़ाइलों को संसाधित करना चाहें:
$ for f in *.jpg ; do convert $f -scale 33% tmp/$f ; done
$ ls -m tmp
cat.jpg, otago.jpg
या, फ़ाइलों को संसाधित करने के बजाय, आपको किसी क्रिया को विशिष्ट संख्या में बार-बार दोहराने की आवश्यकता हो सकती है। ए के लिए लूप के वेरिएबल को आप जो भी डेटा प्रदान करते हैं, उसके द्वारा परिभाषित किया जाता है, ताकि आप एक ऐसा लूप बना सकें जो फाइलों के बजाय संख्याओं पर पुनरावृत्त हो:
{0..4} में n के लिए$ for n in {0..4}; do echo $n ; done
0
1
2
3
4
अधिक लूपिंग
अब आप अपने स्वयं के लूप बनाने के लिए पर्याप्त जानते हैं। जब तक आप लूपिंग में सहज न हों, तब तक उनका उपयोग प्रतियों . पर करें आप जिन फ़ाइलों को संसाधित करना चाहते हैं और जितनी बार संभव हो, अंतर्निहित सुरक्षा उपायों के साथ कमांड का उपयोग करें ताकि आप अपने डेटा को बंद करने और अपूरणीय गलतियाँ न कर सकें, जैसे गलती से फ़ाइलों की एक पूरी निर्देशिका को एक ही नाम पर बदल देना, प्रत्येक दूसरे को अधिलेखित कर देना ।
उन्नत के लिए . के लिए लूप विषय, आगे पढ़ें।
सभी शेल बैश नहीं हैं
के लिए कीवर्ड बैश शेल में बनाया गया है। कई समान शेल एक ही कीवर्ड और सिंटैक्स का उपयोग करते हैं, लेकिन कुछ शेल, जैसे tcsh, एक अलग कीवर्ड का उपयोग करते हैं, जैसे foreach , इसके बजाय।
tcsh में, सिंटैक्स स्पिरिट में समान है लेकिन बैश की तुलना में अधिक सख्त है। निम्नलिखित कोड नमूने में, foreach? string स्ट्रिंग टाइप न करें 2 और 3 पंक्तियों में। यह एक द्वितीयक संकेत है जो आपको सचेत करता है कि आप अभी भी अपना लूप बनाने की प्रक्रिया में हैं।
$ foreach f (*)
foreach? file $f
foreach? end
cat.jpg: JPEG image data, EXIF standard 2.2
design_maori.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced
otago.jpg: JPEG image data, EXIF standard 2.2
waterfall.png: PNG image data, 4608 x 2592, 8-bit/color RGB, non-interlaced
tcsh में, दोनों foreach और समाप्त अलग-अलग पंक्तियों में अकेले दिखाई देना चाहिए, ताकि आप के लिए . नहीं बना सकें बैश और इसी तरह के गोले के साथ एक पंक्ति पर लूप करें।
ढूंढें कमांड वाले लूप के लिए
सिद्धांत रूप में, आपको एक ऐसा शेल मिल सकता है जो के लिए . प्रदान नहीं करता है लूप फ़ंक्शन, या आप अतिरिक्त सुविधाओं के साथ किसी भिन्न कमांड का उपयोग करना पसंद कर सकते हैं।
ढूंढें कमांड के लिए . की कार्यक्षमता को लागू करने का एक और तरीका है लूप, क्योंकि यह आपके लूप में शामिल की जाने वाली फ़ाइलों के साथ-साथ समानांतर प्रसंस्करण के विकल्पों के दायरे को परिभाषित करने के कई तरीके प्रदान करता है।
ढूंढें कमांड आपकी हार्ड ड्राइव पर फाइल खोजने में आपकी मदद करने के लिए है। इसका सिंटैक्स सरल है:आप उस स्थान का पथ प्रदान करते हैं जिसे आप खोजना चाहते हैं, और ढूंढें सभी फाइलों और निर्देशिकाओं को ढूंढता है:
$ find .
.
./cat.jpg
./design_maori.png
./otago.jpg
./waterfall.png
आप नाम का कुछ भाग जोड़कर खोज परिणामों को फ़िल्टर कर सकते हैं:
$ find . -name "*jpg"
./cat.jpg
./otago.jpg
ढूंढें . के बारे में बढ़िया बात यह है कि प्रत्येक फ़ाइल जो उसे मिलती है उसे -exec . का उपयोग करके एक लूप में फीड किया जा सकता है झंडा। उदाहरण के लिए, अपनी उदाहरण निर्देशिका में केवल PNG फ़ोटो को छोटा करने के लिए:
$ find . -name "*png" -exec convert {} -scale 33% tmp/{} \;
$ ls -m tmp
design_maori.png, waterfall.png
-निष्पादन . में खंड, ब्रैकेट वर्ण {} किसी भी वस्तु के लिए खड़े रहें ढूंढें प्रसंस्करण कर रहा है (दूसरे शब्दों में, पीएनजी में समाप्त होने वाली कोई भी फाइल जो स्थित है, एक समय में एक)। -निष्पादन खंड को अर्धविराम से समाप्त किया जाना चाहिए, लेकिन बैश आमतौर पर अर्धविराम का उपयोग करने का प्रयास करता है। आप बैकस्लैश के साथ अर्धविराम से "बच" जाते हैं (\; ) ताकि ढूंढें उस अर्धविराम को उसके समाप्त होने वाले चरित्र के रूप में मानना जानता है।
ढूंढें कमांड जो करता है उसमें बहुत अच्छा है, और यह कभी-कभी बहुत अच्छा भी हो सकता है। उदाहरण के लिए, यदि आप किसी अन्य फोटो प्रक्रिया के लिए पीएनजी फाइलों को खोजने के लिए इसका पुन:उपयोग करते हैं, तो आपको कुछ त्रुटियां मिलेंगी:
$ find . -name "*png" -exec convert {} -flip -flop tmp/{} \;
convert: unable to open image `tmp/./tmp/design_maori.png':
No such file or directory @ error/blob.c/OpenBlob/2643.
...
ऐसा लगता है कि ढूंढें सभी पीएनजी फाइलों का पता लगा लिया है—न केवल वे फाइलें जो आपकी वर्तमान निर्देशिका में हैं (. ) लेकिन वे भी जिन्हें आपने पहले संसाधित किया था और अपने tmp . में रखा था उपनिर्देशिका। कुछ मामलों में, आप ढूंढना want चाह सकते हैं वर्तमान निर्देशिका और उसके भीतर अन्य सभी निर्देशिकाओं (और उन . में सभी निर्देशिकाओं को खोजने के लिए) ) यह एक शक्तिशाली पुनरावर्ती प्रसंस्करण उपकरण हो सकता है, विशेष रूप से जटिल फ़ाइल संरचनाओं में (जैसे संगीत कलाकारों की निर्देशिका जिसमें संगीत फ़ाइलों से भरे एल्बम की निर्देशिका होती है), लेकिन आप इसे -maxdepth के साथ सीमित कर सकते हैं। विकल्प।
वर्तमान निर्देशिका में केवल PNG फ़ाइलें खोजने के लिए (उपनिर्देशिकाओं को छोड़कर):
$ find . -maxdepth 1 -name "*png"
वर्तमान निर्देशिका में फ़ाइलों को खोजने और संसाधित करने के साथ-साथ उपनिर्देशिकाओं का एक अतिरिक्त स्तर, अधिकतम गहराई को 1 से बढ़ाएँ:
$ find . -maxdepth 2 -name "*png"
इसका डिफ़ॉल्ट सभी उपनिर्देशिकाओं में उतरना है।
मज़ा और मुनाफ़े की तलाश में
जितना अधिक आप लूप का उपयोग करते हैं, उतना ही अधिक समय और प्रयास आप बचाते हैं, और जितने बड़े कार्य आप निपटा सकते हैं। आप केवल एक उपयोगकर्ता हैं, लेकिन एक सुविचारित लूप के साथ, आप अपने कंप्यूटर को कड़ी मेहनत करने के लिए मजबूर कर सकते हैं।
आप किसी भी अन्य कमांड की तरह लूपिंग का इलाज कर सकते हैं और करना चाहिए, जब आपको एक या दो को कई फाइलों पर दोहराने की आवश्यकता होती है, तो इसे हाथ में रखते हुए। हालांकि, यह गंभीर प्रोग्रामिंग के लिए एक वैध प्रवेश द्वार भी है, इसलिए यदि आपको किसी भी फाइल पर एक जटिल कार्य पूरा करना है, तो अपने वर्कफ़्लो की योजना बनाने के लिए अपने दिन में से कुछ समय निकालें। यदि आप एक फ़ाइल पर अपना लक्ष्य प्राप्त कर सकते हैं, तो उस दोहराने योग्य प्रक्रिया को के लिए . में लपेटकर लूप अपेक्षाकृत सरल है, और केवल "प्रोग्रामिंग" की आवश्यकता है कि चर कैसे काम करते हैं और संसाधित फ़ाइलों से असंसाधित को अलग करने के लिए पर्याप्त संगठन की समझ है। थोड़े से अभ्यास के साथ, आप एक Linux उपयोगकर्ता से एक Linux उपयोगकर्ता के पास जा सकते हैं जो लूप लिखना जानता है, इसलिए वहाँ से बाहर निकलें और अपने कंप्यूटर को आपके लिए काम करें!