2011-07-04 17 views
6

पर ले जाएं मेरे पास 10,000 निर्देशिकाओं के साथ एक निर्देशिका (निर्देशिका ए) है। मैं उनमें से कुछ को निर्देशिका बी और अन्य को निर्देशिका सी में स्थानांतरित करना चाहता हूं। मैंने एक टेक्स्ट फ़ाइल बनाई जिसमें सभी फाइलों के नाम शामिल हैं जिन्हें मैं निर्देशिका बी में ले जाना चाहता हूं और दूसरा फाइल जो मैं चाहता हूं निर्देशिका सी में जाने के लिए। मैं इन फ़ाइलों को नई निर्देशिकाओं में स्थानांतरित करने के लिए लूप के लिए बैश कैसे लिख सकता हूं।बैश: टेक्स्ट फ़ाइल में सूचीबद्ध फ़ाइलों पर लूप और उन्हें

स्यूडोकोड:

textfileB में फ़ाइल के लिए:
कदम textfileC में निर्देशिका बी

के लिए निर्देशिका एक से फाइल फ़ाइल के लिए: निर्देशिका सेल्सियस के लिए निर्देशिका एक से
कदम फ़ाइल

क्षमा करें यदि यह कहीं और पूछा जाता है, लेकिन मैंने बैश सीखने के लिए घंटों बिताए हैं और मुझे बस यह नहीं मिला है। मैं किसी अन्य धागे में इतना कुछ खोजने में सक्षम नहीं था जिसे मैं समझ सकता था (शायद मुझे सही खोज शब्द नहीं पता)।

मैं कुछ इस तरह है, लेकिन मुझे पाने के लिए यह नहीं काम कर सकता है:

FILES=[dont' know what goes here? An array? A list? 

मैं सिर्फ पाठ फ़ाइल नाम राज्य कर सकते हैं और यदि ऐसा है तो क्या प्रारूप फ़ाइलों की क्या ज़रूरत है होना करने के लिए? name2.ext, name1.ext, या name1.ext name2.ext]

for f in $FILES; do mv $f /B/$f [not sure about the second argument for mv]; done 

THX

BTW मैक OSX 10.6.8 (Snow Leopard) एप्पल टर्मिनल v। 2.1.2/273.1 बैश 3,2

उत्तर

18
cat file-list.txt | while read i; do 
    # TODO: your "mv" command here. "$i" will be a line from 
    # the text file. 
done 
+0

धन्यवाद। यह काम किया। दूसरों के लिए, यहां पूरा आदेश है, जिसे मैंने एक पंक्ति के रूप में दर्ज किया है: cat list_of_files_with.txt | जबकि मैं पढ़ा; एमवी $ i/वॉल्यूम/hard_drive_name/new_destination_directory_name करें; – PatentDeathSquad

+1

@ AquaT33nFan - मैं उद्धरणों में '" $ i "डाल दूंगा ताकि आप रिक्त स्थान और अन्य वर्णों के साथ फ़ाइल नामों को संभाल सकें जो आमतौर पर कमांड लाइन में दिखाई नहीं देते हैं। – asveikau

+1

बधाई हो, आपको अभी [यूयूओसीए] प्राप्त हुआ है (http://partmaps.org/era/unix/award.html) –

3

BASH FAQ entry #1: "How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?"

तो फ़ाइल नाम ही तो mv को दूसरा तर्क सिर्फ निर्देशिका हो सकता है रहेगा। स्क्रिप्ट की

+0

वह बाश अक्सर पूछे जाने वाले प्रश्न शानदार हैं। यह सुनिश्चित करने के लिए फिर से धन्यवाद कि इसमें भरपूर लिंक हैं। :) – sarnold

1

निर्देशिका फ़ाइलों

TO_B=file1.txt 
TO_C=file2.txt 

for file in $TO_B 
do 
mv ${file} B/ 
done 

for file in $TO_C 
do 
mv ${file} C/ 
done 
+0

"... एक पाठ फ़ाइल में सूचीबद्ध ..." –

+0

क्या आप '$ (बिल्ली $ TO_B)' खो रहे हैं? – sarnold

+0

@ $ i ($ $ TO_B) 'का उपयोग करके @र्नॉल्ड' रिक्त स्थान के साथ फ़ाइल नामों को सही ढंग से संभाल नहीं पाएगा। यही कारण है कि मैं अपना जवाब पसंद करता हूं, 'बिल्ली फ़ाइल नाम | जबकि मैं पढ़ता हूं। – asveikau

0

आप मार उपयोग करने के लिए के अपने स्थान होना चाहिए? पर्ल या कॉर्नशेल के बारे में क्या? यहां समस्या यह है कि बैश में हैश कुंजी एरे (कॉर्नशेल और पर्ल डू) नहीं है। इसका मतलब यह है कि ट्रैक करने के लिए कोई आसान तरीका नहीं है कि कौन सी फाइलें कहां जाती हैं। पर्ल में कल्पना करें:

my %directoryB; #Hash that contains files to move to Directory B 
my %directoryC; #Hash that contains files to move to Directory C 

open (TEXT_FILE_B, "textFileB") or die qq(Can't open "textFileB"); 
while (my $line = <TEXT_FILE_B>) { 
    chomp $line; 
    $directoryB{$line} = 1; 
} 
close TEXT_FILE_B; 

open (TEXT_FILE_C, "textFileC") or die qq(Can't open "textFileC"); 
while (my $line = <TEXT_FILE_C>) { 
    chomp $line; 
    $directoryC{$line} = 1; 
} 
close TEXT_FILE_C; 

उपर्युक्त रेखाएं दो हैंश बनाते हैं।

foreach my $file (@directory) { #A little cheating here... 
    if (exists $directoryB{$file}) { 
     move ($file, $directoryB); 
    } elsif (exists $directoryC{$file}) { 
     move ($file, $directoryC) 
} 

मेरे अगर बयान कर सकते हैं: फ़ाइलों निर्देशिका बी में स्थानांतरित करने की जरूरत है कि के लिए एक और फ़ाइलों की जरूरत है कि अब निर्देशिका सी में स्थानांतरित करने की के लिए एक, सब मैं क्या करना है मेरी हैश को देखो और तय है अब यह देखने के लिए देखो कि उस हैश में एक कुंजी परिभाषित की गई है या नहीं। यदि यह है, तो मुझे पता है कि फ़ाइल को उस निर्देशिका में ले जाया जा सकता है। मुझे केवल एक बार दो पाठ फ़ाइलों को पढ़ना होगा। उसके बाद, मेरे दो हैंश स्टोर करेंगे जो फाइलें एक निर्देशिका में जाती हैं और दूसरी तरफ।


हालांकि, हम हैश की जरूरत नहीं है, तो हम grep इस्तेमाल करेंगे, तो फ़ाइल नाम निर्देशिका में है देखने के लिए। मुझे लगता है कि आपके पास प्रत्येक पंक्ति पर एक फ़ाइल नाम है।

ls | while read file 
do 
    if grep -q "^${file}$" textFileB 
    then 
     mv $file $directoryB 
    elif grep -q "^${file}$" textFileC 
    then 
     mv $file $directoryC 
    fi 
done 

grep -q अपने दो पाठ फ़ाइलों खोज करते हैं मिलान फ़ाइल नहीं है देखने के लिए होगा। यदि ऐसा है, तो यह फ़ाइल को उस निर्देशिका में ले जायेगा। यह बहुत ही कुशल नहीं है क्योंकि इसे हर बार पूरी टेक्स्ट फ़ाइल को खोजना पड़ता है। हालांकि, यह बहुत ही कुशल है, और आप केवल 10,000 फाइलों की बात कर रहे हैं, इसलिए पूरे ऑपरेशन में केवल कुछ मिनट लग सकते हैं।

1

आप 1000 या 1000 उपयोगकर्ता निर्देशिका को बिना समय के ले जा सकते हैं जहां हजारों उपयोगकर्ता निर्देशिका मौजूद हैं।

cat deleteduser | while read i; do mv -vv $i ../deleted_user; done; 
deleteuser= user name list 
../deleted_user= destination dir 
संबंधित मुद्दे