प्रत्येक फ़ाइल को ले जाएँ जो एक निर्देशिका नहीं है


14

मेरे पास एक निर्देशिका है जिसे मैं साफ करने की कोशिश कर रहा हूं जिसमें फाइलें और उपनिर्देशिका दोनों शामिल हैं। मैं जो करने की कोशिश कर रहा हूं वह सरल है: सभी फाइलों को किसी अन्य निर्देशिका में स्थानांतरित करें, लेकिन वे सभी उप-निर्देशिकाओं को छोड़ दें जैसे वे हैं।

मैं कुछ ऐसा सोच रहा हूँ:

mv [*_but_no_dirs] ./other_directory

ऐसा लगता है कि वाइल्डकार्ड *और रेगेक्स के साथ ऐसा करने का एक सरल तरीका होना चाहिए ...

किसी के पास विचार हैं?


1
इसलिए सब फाइल्स को एक सबफ़ोल्डर में ले जाएँ, लेकिन सबडायरेक्ट्रीज़ में किसी को अनदेखा करें?
विल्फ

@Ilff: बिल्कुल सही।
प्रश्न

2
Zsh में, आप कर सकते हैं mv **/*(.) ./other_directory- बैश के साथ आपको बाहरी आदेशों का सहारा लेना होगा find, हालांकि।
गॉडलीजेक

जवाबों:


12

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

tmp=$(TMPDIR=.. mktemp -d)
mv -- */ "$tmp"
mv -- * "$tmp"/other_directory/
mv "$tmp"/* .
rmdir "$tmp"

प्रकारों से फ़ाइलों का मिलान करने का एक मानक तरीका कॉल करना है find

find . -name . -o -type d -prune -o -exec sh -c 'mv "$@" "$0"' other_directory/ {} +

Zsh में, आप फ़ाइलों को मैच के लिए ग्लोब क्वालिफायर का उपयोग कर सकते हैं । .क्वालीफायर नियमित फ़ाइलों का मिलान; ^/सभी गैर-निर्देशिकाओं का मिलान करने के लिए या निर्देशिकाओं के -^/प्रतीकात्मक लिंक का उपयोग करने के लिए भी।

mv -- *(.) other_directory/

किसी भी शेल में, आप बस लूप कर सकते हैं।

for x in *; do
   if ! [ -d "$x" ]; then
     mv -- "$x" other_directory/
   fi
done

8

आप कुछ का उपयोग कर सकते हैं

find . -maxdepth 1 \( ! -type d \) -exec sh -c 'mv  "$@" MYDIR' _ {} \;

पहले हम findकेवल वर्तमान निर्देशन के भीतर देखने के लिए उपयोग करते हैं, फिर हम निर्देशिकाओं की उपेक्षा करते हैं और ! -type d अंत में हम shगंतव्य डायर के लिए सब कुछ निष्पादित करते हैं और स्थानांतरित करते हैं। आप {} +अंत में कोशिश कर सकते हैं जो तेज होगा।


2
थोड़ा सा स्पष्टीकरण, कृपया ...
प्रश्न-पत्र

1
@Questionmark मैंने उत्तर को अपडेट कर दिया है और कुछ स्पष्टीकरण जोड़ा है। इसके अलावा, यह mywiki.wooledge.org/UsingFind पर
वैलेंटाइन

आप -exec sh -c 'mv "$@" MYDIR' _ {} \;इसके बजाय सुझाव क्यों देते हैं -exec mv {} MYDIR \;? बस कुछ है कि \;एक को बदलने के द्वारा सुव्यवस्थित किया जा सकता है पाने के लिए +? आप -exec mv -t MYDIR {} +फॉर्म के साथ ऐसा कर सकते हैं ।
स्कॉट

@ सच में मुझे -tध्वज के बारे में कोई जानकारी नहीं थी । मैंने जवाब में यह भी बताया कि +यह तेज है लेकिन सभी findसंस्करण इसका समर्थन नहीं करते हैं। तो उपरोक्त कोड findउपयोग किए गए किसी भी या शेल के साथ बहुत अधिक संगत है।
वैलेंटाइन बजरमी

1
@ val0x00ff: "... उपरोक्त कोड findउपयोग किए गए किसी भी या शेल के साथ बहुत अधिक संगत है।" यह सच है, लेकिन ऐसा है find … -exec mv {} MYDIR \;, और इससे कम संसाधनों का उपयोग करता है … -exec sh -c 'mv "$@" MYDIR' _ {} \;
स्कॉट

0

यह संभावित रूप से थोड़ा खतरनाक है लेकिन

cp * destination/
rm *

के रूप में दोनों सीपी और आरएम -r स्विच के बिना निर्देशिकाओं पर काम नहीं करेगा।


-1

मेरा सुझाव है कि बस mv *.* destination/गंतव्य के साथ कर रहे हैं / आप जिस फ़ोल्डर में जा रहे हैं।



2
निर्देशिका नामों में 'डॉट' हो सकता है और फ़ाइल नाम इसे बाहर कर सकते हैं (और अक्सर करते हैं) इसलिए *.*कुछ निर्देशिकाओं को स्थानांतरित करेंगे और कुछ फाइलें छोड़ देंगे, जो कि पूछने वाला नहीं चाहता था।
dave_thompson_085

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.