2010-05-06 19 views
17

मेरे पास एक मेनिफेस्ट फ़ाइल है जो केवल न्यूलाइन से अलग फ़ाइल नामों की एक सूची है। किसी फ़ोल्डर से मैनिफेस्ट में नामित सभी फ़ाइलों को मैं कैसे हटा सकता हूं?बाश: मैनिफेस्ट में नामित सभी को छोड़कर सभी फ़ाइलों को कैसे हटाएं?

मैं एक find ./ ! -name "filename" आदेश गतिशील निर्माण करने के लिए कोशिश की है:

command="find ./ ! -name \"MANIFEST\" " 
for line in `cat MANIFEST`; do 
    command=${command}"! -name \"${line}\" " 
done 
command=${command} -exec echo {} \; 
$command 

लेकिन फ़ाइलों रहते हैं।

[नोट:] मुझे पता है कि यह गूंज का उपयोग करता है। मैं यह जांचना चाहता हूं कि इसका उपयोग करने से पहले मेरा आदेश क्या करता है।

समाधान: (धन्यवाद PixelBeat)

ls -1 > ALLFILES 
sort MANIFEST MANIFEST ALLFILES | uniq -u | xargs rm 

अस्थायी फ़ाइल के बिना:

ls -1 | sort MANIFEST MANIFEST - | uniq -u | xargs rm 

दोनों की उपेक्षा है कि क्या फ़ाइलें नहीं हल कर रहे हैं /।

+0

धन्यवाद सभी! मैं इसे अपने शेल गाइड के लिए पिक्सेलबीट दे रहा हूं जिसमें समाधान – brice

उत्तर

11

"सेट अंतर" पैटर्न का उपयोग http://www.pixelbeat.org/cmdline.html#sets से

(find ./ -type f -printf "%P\n"; cat MANIFEST MANIFEST; echo MANIFEST) | 
    sort | uniq -u | xargs -r rm 

नोट मैं MANIFEST सूची में दो बार के मामले में है कि वास्तव में मौजूद नहीं हैं वहाँ सूचीबद्ध फ़ाइलें हैं। यह भी ध्यान रखें ऊपर उपनिर्देशिका में फ़ाइलों का समर्थन करता

+0

था, मुझे आपके आदेश पर 'rm: missing operand' मिलता है। मैंने बस इसे ls, comm, और xargs का उपयोग करके समझ लिया। धन्यवाद वैसे भी पीबी – brice

+0

उस चेतावनी को हटाने के लिए xrs को जोड़ें (जब किसी भी फाइल को हटाने की आवश्यकता नहीं है) – pixelbeat

+1

इसके बजाए 'grep' का उपयोग करके अंतर पैटर्न सेट करें: 'find ./ -type f -printf"% P \ n "| fgrep -vf MANIFEST | ... ' –

3

यह सोचा बाहर:

ls -1 > ALLFILES 
comm -3 MANIFEST ALLFILES | xargs rm 
+2

हाँ comm -3 उपरोक्त मेरे समाधान के बराबर है। लेकिन सावधान रहें क्योंकि कम से कम सॉर्ट किए गए इनपुट – pixelbeat

+0

चीयर्स को उम्मीद नहीं है, जो बिना छेड़छाड़ के सेट अंतर का उपयोग करके उत्साहित हैं। – brice

+1

यदि आपके फ़ाइल नामों में रिक्त स्थान हैं तो 'xargs -L 1' का उपयोग करें। – djjeck

0

मानता है कि MANIFEST पहले से ही क्रमित है:

find -type f -printf %P\\n | sort | comm -3 MANIFEST - | xargs rm 
1
बस मस्ती के लिए

, एक पर्ल 1-लाइनर ... इस मामले में वास्तव में जरूरी नहीं है, लेकिन यदि आप कुछ फैनसीयर चाहते हैं तो बैश की तुलना में अधिक अनुकूलन योग्य/एक्स्टेंसिबल :)

$ ls 
1 2 3 4 5 M 
$ cat M 
1 
3 
$ perl -e '{use File::Slurp; %M = map {chomp; $_ => 1} read_file("M"); $M{M}=1; \ 
foreach $f (glob("*")) {next if $M{$f}; unlink "$f"||die "Can not unlink: $!\n" };}' 
$ ls 
1 3 M 

ऊपर भी कम करता है, तो आप प्रकट STDIN

perl -e '{%M = map {chomp; $_ => 1} <>; $M{M}=1; \ 
foreach $f (glob("*")) {next if $M{$f};unlink "$f"||die "Can not unlink: $!\n" };}' M 
13

पर प्रत्येक फ़ाइल के लिए मौजूदा निर्देशिका में मैनिफ़ेस्ट फ़ाइल में ग्रेप फ़ाइल नाम और rmफ़ाइल यदि मिलान नहीं पारित हो सकता है।

for file in * 
    do grep -q -F "$file" PATH_TO_YOUR_MANIFIST || rm "$file" 
done 
+1

यदि आप इस विधि का उपयोग करते हैं, तो अपने मैनिफेस्ट फ़ाइल का नाम मेनिफेस्ट में जोड़ना सुनिश्चित करें, यदि आप इसे उसी निर्देशिका में डाल रहे हैं जहां आप फ़ाइलों को हटा रहे हैं। यदि आप इस कोड को एक स्क्रिप्ट में रखते हैं, तो उस स्क्रिप्ट का नाम मैनिफेस्ट में भी जोड़ें। –

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