2012-07-30 18 views
9

चलो कहते हैं कि मैं अपने वर्तमान निर्देशिका में निम्न फ़ाइलों करते हैं:बैश कमांड केवल कुछ फाइलों को स्थानांतरित करने के लिए?

1.jpg 
1original.jpg 
2.jpg 
2original.jpg 
3.jpg 
4.jpg 

वहाँ एक टर्मिनल/bash/लिनक्स कमांड उस तरह

if the file [an integer]original.jpg exists, 
    then move [an integer].jpg and [an integer]original.jpg to another directory. 

इस तरह के एक आदेश निष्पादित कुछ कर सकते हैं 1 कारण होगा है। jpg, 1original.jpg, 2.jpg और 2original.jpg अपनी निर्देशिका में होने के लिए।

नोट यह एक आदेश नहीं होना चाहिए। मैं सरल आदेशों का संयोजन हो सकता हूं। हो सकता है कि कुछ मूल फाइलों को एक नई निर्देशिका में कॉपी करें। फिर पुरानी निर्देशिका से फ़ाइल नामों की एक सूची प्राप्त करने के लिए नए डीआईआर में फाइलों पर कुछ नियमित अभिव्यक्ति फ़िल्टर करें, जिन्हें अभी भी प्रतिलिपि बनाने की आवश्यकता है ..

+3

यही कारण है कि सुपरसर्स प्रोग्रामिंग सीखते हैं :) अच्छा सवाल। –

+0

क्या आपको उस मामले के बारे में चिंता करने की ज़रूरत है, जहां कहें, '5original.jpg' लेकिन' 5.jpg' नहीं? –

उत्तर

6

विस्तारित ग्लोब समर्थन को चालू करने से आप नियमित-अभिव्यक्ति-जैसे पैटर्न लिखने की अनुमति देंगे। यह '87 .jpg 'और' 87original.jpg 'जैसे बहु-अंकों वाले पूर्णांक वाले फ़ाइलों को संभाल सकता है। बैश पैरामीटर विस्तार तब ओ नाम से "मूल" पट्टी करने के लिए इस्तेमाल किया जा सकता है एफ एक मिली फाइल है जो आपको दो संबंधित फाइलों को एक साथ स्थानांतरित करने की अनुमति देती है।

shopt -s extglob 
for f in +([[:digit:]])original.jpg; do 
    mv $f ${f/original/} otherDirectory 
done 

एक विस्तारित पैटर्न में, +(x) मैचों में से एक या अधिक चीजों की कोष्ठकों के अंदर, नियमित अभिव्यक्ति x+ के अनुरूप। यहां, x कोई अंक है। इसलिए, हम वर्तमान निर्देशिका में सभी फ़ाइलों से मेल खाते हैं जिनके नाम में 1 या अधिक अंक होते हैं, जिसके बाद "original.jpg" होता है।

${f/original/}bash पैटर्न प्रतिस्थापन का एक उदाहरण है। यह f के मान से स्ट्रिंग "मूल" की पहली घटना को हटा देता है। तो यदि f स्ट्रिंग "1original.jpg" है, तो ${f/original/} स्ट्रिंग "1.jpg" है।
यह विफल हो जाता है, तो वहाँ मौजूद original.jpg और .jpg दोनों: यदि पूर्णांक नहीं

संपादित

-1

आप फ़ाइलों के नामों में "मैचों" को खोजने के लिए रेगेक्स स्टेटमेंट का उपयोग कर सकते हैं आप देख रहे हैं फिर अपने कार्यों को "मैचों" पर करें जो आपको मिलते हैं।

+1

धन्यवाद, क्या आप ऊपर दिए गए फ़ाइल नामों के आधार पर एक उदाहरण समाधान दिखा सकते हैं? मैं नमूना समाधान – John

-1

integer=0; while [ $integer -le 9 ] ; do if [ -e ${integer}original.jpg ] ; then mv -vi ${integer}.jpg ${integer}original.jpg lol/ ; fi ; integer=$[ $integer + 1 ] ; done

ध्यान दें कि यहाँ, "lol" गंतव्य निर्देशिका है। आप इसे अपनी पसंद के अनुसार बदल सकते हैं। इसके अलावा, आप में while [ $integer -le 9 ] में 9 से अधिक पूर्णांक जांचने के लिए 9 बदल सकते हैं। अभी यह 0 * से शुरू होता है और 9 * की जांच के बाद बंद हो जाता है।

संपादित करें: यदि आप चाहते हैं, तो आप मेरे कोड में अर्धविराम को कैरिज रिटर्न के साथ प्रतिस्थापित कर सकते हैं और इसे पढ़ना आसान हो सकता है। साथ ही, आप पूरे ब्लॉक को इस तरह टर्मिनल में पेस्ट कर सकते हैं, भले ही वह तुरंत स्पष्ट न हो।

+3

देखने से सबसे अच्छा सीखता हूं आपको अपने कोड को ऐसे तरीके से स्वरूपित करने पर विचार करना चाहिए जो पढ़ने और बनाए रखने में आसान हो। – jordanm

3

अच्छी तरह से, सीधे नहीं, लेकिन यह एक oneliner (: अब और नहीं संपादित करें): है

for i in [0-9].jpg; do 
    orig=${i%.*}original.jpg 
    [ -f $orig ] && mv $i $orig another_dir/ 
done 

संपादित करें:

  • for i in [0-9].jpg: शायद मैं अपने समाधान का कहना है चाहिए के लिए पाश शरीर पर अमल फ़ाइल नाम के रूप में एक संख्या के साथ प्रत्येक जेपीजी फ़ाइल। $i
  • orig={i%.*}original.jpg में पूरी फ़ाइल नाम की दुकान: "मूल फ़ाइल"
  • [ -f $orig ] के लिए संभव फ़ाइल नाम $orig में सहेजें: test(1) ([ ... ] सामान) यदि $i के लिए मूल फ़ाइल मौजूद है के माध्यम से जाँच करें। यदि हां, तो दोनों फ़ाइलों को another_dir पर ले जाएं। यह && के माध्यम से किया जाता है: परीक्षण के सफल होने पर इसके बाद का हिस्सा केवल तभी निष्पादित किया जाएगा।
+1

आपको अपने कोड को कई लाइनों पर प्रारूपित करना चाहिए ताकि इसे पढ़ना आसान हो। साथ ही, आप इसके बजाय '$ {i ## * /}' के साथ बेसनाम का उपयोग करने से बच सकते हैं। – jordanm

+0

धन्यवाद। बेसनाम से परहेज करना और पैटर्न मिलान का उपयोग करना एक अच्छा विचार है, लेकिन '$ {i ## * /} 'मेरे लिए काम नहीं करता है। मैंने '$ {i%। *} 'का उपयोग किया। – lewurm

1

निम्नलिखित काम करते हैं और (अपनी संख्या की वास्तविक सीमा के साथ उत्पादन निर्देशिका के साथ out, और {1..9} की जगह समझने में आसान है जाएगा।

for x in {1..9} 
do 
if [ -e ${x}original.jpg ] 
then 
mv $x.jpg out 
mv ${x}original.jpg out 
fi 
done 

आप स्पष्ट रूप से भी यह एक पंक्ति के रूप में दर्ज कर सकते हैं

+3

बिना स्पष्टीकरण के पूरी तरह से वैध उत्तर डाउनवॉटिंग व्यर्थ है ... – houbysoft

2

यह किसी भी सख्ती से संख्यात्मक उपसर्ग के लिए काम चाहिए, जैसे कि 234.jpg

for f in *original.jpg; do 
    pre=${f%original.jpg} 
    if [[ -e "$pre.jpg" && "$pre" -eq "$pre" ]] 2>/dev/null; then 
    mv "$f" "$pre.jpg" targetDir 
    fi 
done 

"$pre" -eq "$pre" एक त्रुटि देता है।
$pre तब nullstring है और "$pre" -eq "$pre" सत्य है।

संबंधित मुद्दे