mv: स्टेट नहीं कर सकता है शेल स्क्रिप्ट में ऐसी कोई फ़ाइल या निर्देशिका नहीं है


16

मैंने कुछ फ़ाइलों को स्थानांतरित करने के लिए एक स्क्रिप्ट लिखी है, एक फ़ोल्डर को दूसरे फ़ोल्डर में ले जाता है, लेकिन मुझे निम्न त्रुटि मिली, मैंने 2 फ़ोल्डर्स की जाँच की और 1 फ़ोल्डर के लिए नोटिस ऐसी फ़ाइलें हैं और दूसरी ऐसी कोई फ़ाइल नहीं है, लेकिन उन सभी को "mv" क्यों दिखाया गया है ऐसी कोई फ़ाइल या निर्देशिका नहीं स्टेट कर सकते हैं "

    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/194.199.68.165_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/194.42.17.124_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/195.113.161.13_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/203.159.127.3_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/212.199.61.205_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/212.51.218.235_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/213.73.40.105_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/41.225.7.4_tcp.folder/data/*': No such file or directory
    mv: cannot stat `/home/esolve/project/capture/tcp_50x50/dest_folder/83.230.127.122_tcp.folder/data/*': No such file or directory
    [esolve@kitty tcp_50x50]$ ls /home/wgong/project/capture/tcp_50x50/dest_folder/194.199.68.165_tcp.folder/
    [esolve@kitty tcp_50x50]$ ls /home/wgong/project/capture/tcp_50x50/dest_folder/203.159.127.3_tcp.folder/data/
    129.88.70.226   132.187.230.1    138.96.116.22   155.185.54.250   192.38.109.144  193.136.227.163  193.175.135.61  195.113.161.13  83.230.127.122
    130.104.72.200  132.227.62.122   147.83.29.232   156.17.10.52     192.42.43.22    193.137.173.218  193.205.215.74  212.199.61.205
    131.130.69.164  132.252.152.194  148.81.140.193  157.181.175.249  192.43.193.71   193.144.21.131   193.226.19.30   212.51.218.235
    131.188.44.102  134.151.255.180  152.66.245.162  160.78.253.31    193.1.170.136   193.145.46.243   194.199.68.165  213.73.40.105
    131.254.208.10  138.48.3.203     152.81.47.4     192.114.4.3      193.136.166.56  193.166.160.98   194.42.17.124   41.225.7.4

स्क्रिप्ट है:

    list=`ls dest_folder`
    cd dest_folder
    cwd=`pwd`
    for folder in $list;do
            mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
    done

मैंने उसे अंदर दौड़ाया /home/esolve/project/capture/tcp_50x50/


1
कृपया स्क्रिप्ट के संबंधित भागों को दिखाएं।
चटाई

मैंने अपना प्रश्न अपडेट किया और स्क्रिप्ट को जोड़ा, धन्यवाद!
मिस्टीज

यदि आप एक जोड़ने की आवश्यकता है -rके लिए mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}?
व्यावसायिक

वहाँ कोई -rविकल्प नहीं हैmv
misteryes

जवाबों:


25
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}

'वहां के उद्धरण ( ) शेल को ग्लोबिंग करने से रोकते हैं। *करने के लिए सचमुच भेजी जा रही है mvआदेश है, जो बाद से यह कहा जाता फ़ाइलें नहीं मिल रहा है विफल रहता *निर्देशिका संकेत दिया है।

इसे इसमें बदलें:

mv "${cwd}/${folder}/data"/* "${cwd}/${folder}"

(यदि आप कभी भी इसमें रिक्त स्थान के साथ निर्देशिका नाम रखते हैं *, तो उद्धरणों के बाहर डबल कोटेशन।)

आप अभी भी खाली निर्देशिका के लिए त्रुटियों को प्राप्त करेंगे। (एक ही तरह का कारण: यदि फ़ाइल पैटर्न के लिए मेल नहीं खाती है, तो यह पैटर्न को कमांड के तर्क के रूप में पास करता है।)


दोहरे उद्धरण से समझ में आता है, लेकिन मुझे *उद्धरण के बाहर रखने की आवश्यकता क्यों है ?
सिब्ब्स जुआ जू

यदि आप इसे विस्तारित करना चाहते हैं, तो आपको इसके बाहर की जरूरत है @SibbsGambling
Mat

8

आपके कोड के साथ कई समस्याएं हैं:

list=`ls dest_folder`

आप lsअनुगामी newlines वर्ण के बिना के उत्पादन का भंडारण कर रहे हैं $listlsन्यूलाइन वर्णों के साथ अलग किए गए फ़ाइल नामों की सूची को आउटपुट करता है। newlineफ़ाइल नाम में किसी भी पात्र के रूप में मान्य है, ताकि आउटपुट का उपयोग मज़बूती से न किया जा सके। उदाहरण के lsलिए एक निर्देशिका के लिए आउटपुट जिसमें सम्‍मिलित है aऔर एक निर्देशिका के bलिए वही है जिसमें एक फाइल है a<newline>b

 cd dest_folder

आप उस आदेश की विफलता के लिए जाँच नहीं कर रहे हैं। सामान्य तौर पर आपको कमांडों के निकास की स्थिति की जांच करनी चाहिए, लेकिन यह विशेष रूप से सच है cd, क्योंकि बाकी कमांड मान लेते हैं कि आप उस नई निर्देशिका में हैं, और जब आप नहीं हैं तो नाटकीय परिणाम हो सकते हैं।

cwd=`pwd`

POSIX गोले $PWDचर में मौजूदा निर्देशिका के लिए (एक) पथ को पहले से ही बनाए रखते हैं , इसलिए आपको pwdयहां उपयोग करने की आवश्यकता नहीं होनी चाहिए (विशेष रूप से सामान्य स्थिति में क्योंकि कमांड प्रतिस्थापन पथ से नई पंक्ति वर्णों को हटा देगा)। इसके अलावा, mvसापेक्ष रास्तों को स्वीकार करता है , इसलिए आपको पूर्ण पथ बनाने की आवश्यकता नहीं है।

for folder in $list;do

एक चर को छोड़ना , खोल में विभाजित + ग्लोब ऑपरेटर है। यही है, चर की सामग्री विभाजित है ( $IFSव्हॉट्सएप वालों के लिए विशेष नियमों के साथ उल्लिखित विभाजकों पर ), और विभाजन के परिणामस्वरूप प्रत्येक तत्व को वाइल्डकार्ड वर्णों के लिए देखा जाता है ताकि उन्हें मिलान फ़ाइलों की सूची में विस्तारित किया जा सके।

यहाँ, आप बंटवारे को चाहते हैं, लेकिन केवल नईलाइन वर्णों पर, और आप ग्लोबिंग नहीं चाहते हैं, इसलिए आपको इसे अक्षम करना होगा:

 IFS='
 '; set -f
 for folder in $list
   mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}

फिर से, एक वैरिएबल को छोड़ने पर विभाजित + ग्लोब ऑपरेटर होता है। यहां, आप न तो चाहते हैं, इसलिए आपको उन चर को उद्धृत करने की आवश्यकता है।

जैसा कि पहले ही उल्लेख किया गया है, वाइल्डकार्ड का विस्तार केवल तब किया जाता है, जब आपको *उद्धरण से बाहर निकलने की आवश्यकता नहीं होती है । यदि आपने पहले ग्लोबिंग को निष्क्रिय कर दिया है set -f, तो आपको set +fउस कमांड को कॉल करने से पहले इसे फिर से स्थापित करना होगा ।

इसे लिखने का एक बेहतर तरीका होगा:

cd dest_folder &&
  for folder in */;do
    mv -- "${folder}data/"* "$folder"
  done

हालांकि कुछ नोट:

  • यह छिपे हुए फ़ोल्डरों को बाहर कर देगा और फ़ोल्डरों से छिपी हुई फ़ाइलों को स्थानांतरित नहीं करेगा data
  • हम प्रक्रिया में ओवरराइड की जा रही फ़ाइलों की जाँच नहीं कर रहे हैं (आप -iविकल्प जोड़ना चाहते हैं mv)।
  • उपयोग करके */, हम केवल निर्देशिकाओं पर लूपिंग कर रहे हैं , लेकिन इसमें निर्देशिकाओं के प्रतीकात्मक लिंक भी शामिल हैं। यदि आप नहीं चाहते हैं, तो आपको [ -L "${folder%/}" ] && continueलूप के अंदर जोड़ना होगा ।
  • अगर वहाँ कोई गैर-छिपा हुआ फ़ोल्डर नहीं */है, तो वह अपने आप विस्तृत हो जाएगा, इसलिए आपको mvयह कहने से त्रुटि संदेश प्राप्त होगा कि उसे एक फ़ाइल नहीं मिली है */data/*। इसी तरह, यदि किसी भी फ़ोल्डर में कोई गैर-छिपी हुई फ़ाइल नहीं है, तो आपको एक त्रुटि संदेश मिलेगा जो that-folder/data/*मौजूद नहीं है।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.