ফাইল সরিয়ে ফেলুন তবে সমস্ত ফাইলকে তালিকায় বাদ দিন


17

আমার পর্যায়ক্রমে একটি ফোল্ডার পরিষ্কার করা দরকার। আমি একটি ফাইললিস্ট পেয়েছি যাতে পাঠ্য থাকে, কোন ফাইলগুলি অনুমোদিত। এখন আমাকে সমস্ত ফাইল মুছতে হবে যা এই ফাইলটিতে নেই।

উদাহরণ:

dont-delete.txt:

dontdeletethisfile.txt
reallyimportantfile.txt
neverdeletethis.txt
important.txt

আমার ফোল্ডারটি ক্লিন-আপে এটি উদাহরণ হিসাবে রয়েছে:

ls /home/me/myfolder2tocleanup/:

dontdeletethisfile.txt
reallyimportantfile.txt
neverdeletethis.txt
important.txt
this-can-be-deleted.txt
also-waste.txt
never-used-it.txt

সুতরাং এই ফাইলগুলি মুছে ফেলা উচিত:

this-can-be-deleted.txt
also-waste.txt
never-used-it.txt

আমি ফাইলের দ্বারা সরবরাহিত কিছু ফাইল বাদ দেওয়ার বিকল্পের সাথে একটি মুছুন কমান্ড তৈরি করতে কিছু অনুসন্ধান করি।


এটা কি হোমওয়ার্ক?
mook765

আমি আশা করি আপনি তাঁর শিক্ষক নন lol
গুজরাট সান্টানা

2
@ গুজরাত আমরা হোমওয়ার্ক পরিষেবা ফ্রি নই, তাই মন্তব্যটি ন্যায়সঙ্গত। প্রশ্নটি নিজেই, এটি অন্যের পক্ষে কার্যকর হতে পারে, তাই এটি এখন পর্যন্ত খোলা।
সের্গেই কোলোডিয়াজনি

@ সার্জ আমি সম্পূর্ণরূপে আপনার সাথে একমত
গুজরাট সান্টানা

উত্তর:


9

rmকমান্ড তাই আউট মন্তব্য যে আপনি চেক করুন এবং যাচাই করুন যে এটি হিসাবে প্রয়োজন কাজ করছে পারবেন না। তারপরে কেবল সেই লাইনটি আন-মন্তব্য করুন।

check directoryঅধ্যায় নিশ্চিত আপনি দূর্ঘটনাক্রমে ভুল ডিরেক্টরি থেকে স্ক্রিপ্ট চালাতে না ও ভুল ফাইল পরাস্ত হবে।

আপনি echo deletingনিঃশব্দে চালানোর জন্য লাইনটি সরাতে পারেন ।

#!/bin/bash

cd /home/me/myfolder2tocleanup/

# Exit if the directory isn't found.
if (($?>0)); then
    echo "Can't find work dir... exiting"
    exit
fi

for i in *; do
    if ! grep -qxFe "$i" filelist.txt; then
        echo "Deleting: $i"
        # the next line is commented out.  Test it.  Then uncomment to removed the files
        # rm "$i"
    fi
done

আপনার কোডটি অযথাযুক্ত ব্যবহারls এবং আউটপুটটির অকেজো ক্যাপচারিং এড়ানোর জন্য আমি সম্পাদনা করেছি grepযদি আপনি জানতে চান যে কোনও ম্যাচ আছে কি না। সমস্যাগুলি এড়ানোর জন্য আমি স্থির স্ট্রিং প্যাটার্নগুলিও ব্যবহার করেছি।
ডেভিড ফোস্টার

@ ডেভিডফোরস্টার অবদানের জন্য ধন্যবাদ যাইহোক, যখন আপনি পরিবর্তিত whileএকটি লুপ forলুপ আপনি অনবধানতাবশত পরিবর্তিত iteration keyথেকে iথেকে f। ঘোষণাপত্রে, যা কোডটি ভেঙে দিয়েছে। আমি এটা ঠিক করেছি.
এলডি জেমস

উফ, অভ্যাসের বল আমি যেমন ফাইলের নামের জন্য শেল ভেরিয়েবলের নাম সংক্ষেপিত করি f। ;- পি (… এবং আপনার উত্তরটির জন্য আমি +1 যা আমি আগে ভুলে গিয়েছি))
ডেভিড ফোস্টার

10

এই অজগর লিপিটি এটি করতে পারে:

#!/usr/bin/env python3
import os
no_remove = set()
with open('./dont-delete.txt') as f:
     for line in f:
         no_remove.add(line.strip())

for f in os.listdir('.'):
    if f not in no_remove:
        print('unlink:' + f ) 
        #os.unlink(f)

গুরুত্বপূর্ণ অংশটি হ'ল os.unlink()ফাংশনটিকে সংঘাতবদ্ধ করা ।

দ্রষ্টব্য : এই স্ক্রিপ্টটি এবং dont-delete.txtআপনার সাথে যুক্ত করুন dont-delete.txtযাতে তারা উভয় তালিকায় থাকে এবং তাদের একই ডিরেক্টরিতে রাখে।


1
আমি setদ্বিতীয় কোডে ও (এন) এর পরিবর্তে ও (1) এর পরিবর্তে তালিকার একটি পরিবর্তে আপনার কোডটি পরিবর্তন করেছি ।
ডেভিড ফোস্টার

আপনার সহায়তার জন্য ধন্যবাদ, আমি সাধারণত উইন্ডোজ লোক, তবে
অজগরটি

1
@ স্টেফান ৩৩: পাইথন উইন্ডোজে ঠিক একইভাবে চলে।
ডেভিড ফোস্টার

3

এখানে একটি ওয়ান-লাইনার:

comm -2 -3 <(ls) <(sort dont_delete) | tail +2 | xargs -p rm
  1. ls বর্তমান ডিরেক্টরিতে সমস্ত ফাইল মুদ্রণ করে (সাজানো ক্রমে)
  2. sort dont_delete সাজানো ক্রমে আমরা মুছে ফেলতে চাই না এমন সমস্ত ফাইল মুদ্রণ করে
  3. <()অপারেটর একটি ফাইল মত বস্তুর মধ্যে একটি স্ট্রিং সক্রিয়
  4. commকমান্ড আউট লাইন যার উপর তারা বিসদৃশ্য দুই প্রাক সাজানো ফাইল এবং কপি করে প্রিন্ট তুলনা
  5. -2 -3পতাকা ব্যবহারের ফলে commপ্রথম ফাইলটিতে কেবল মুদ্রিত রেখাগুলি থাকবে তবে দ্বিতীয়টি নয়, যা মুছে ফেলা নিরাপদে থাকা ফাইলগুলির তালিকা হবে
  6. tail +2কল শুধু শিরোনাম অপসারণ করা হয় commআউটপুট, যা ইনপুট ফাইল নাম রয়েছে
  7. এখন আমরা স্ট্যান্ডার্ড আউট মুছে ফেলার জন্য ফাইলগুলির একটি তালিকা পাই। আমরা এই আউটপুটটি পাইপ করি xargsযার ফলে আউটপুট প্রবাহকে আর্গুমেন্টের তালিকায় পরিণত করবে rm-pবিকল্প শক্তির xargsনির্বাহ পূর্বে নিশ্চিতকরণ জন্য জিজ্ঞাসা করতে।

আপনার সহায়তার জন্য THX, এখন আমার সমাধান আছে!
stefan83

@ গ্রেডেনহেড, আমি আপনার কোডটি ক্লান্ত করেছি কিন্তু এটি ডিরেক্টরিতে থাকা সমস্ত ফাইল সরিয়ে দেয় এবং কেবলমাত্র প্রথম এবং শেষ ফাইলটি ডান-ডিলিট তালিকায় রাখে। এই সমস্যার জন্য আপনার কি কোনও ধারণা আছে? আগাম ধন্যবাদ.
নেগার

1

FWIW দেখে মনে হচ্ছে আপনি গ্লোব কোয়ালিফায়ার zshব্যবহার করে স্থানীয়ভাবে এটি করতে পারেন (+cmd)

উদাহরণস্বরূপ, আসুন কিছু ফাইল দিয়ে শুরু করা যাক

 % ls
bar  baz  bazfoo  keepfiles.txt  foo  kazoo

এবং একটি শ্বেত তালিকা ফাইল

 % cat keepfiles.txt
foo
kazoo
bar

প্রথমে শ্বেত তালিকাটি একটি অ্যারেতে পড়ুন:

 % keepfiles=( "${(f)$(< keepfiles.txt)}" )

বা সম্ভবত আরও ভাল

 % zmodload zsh/mapfile
 % keepfiles=( ${(f)mapfile[./keepfiles.txt]} )

( mapfileবাশের বিল্টিনের সমতুল্য - বা এর প্রতিশব্দ readarray)। এখন আমরা পরীক্ষা করতে পারি যে অ্যারেতে কোন কী (ফাইলের নাম) বিদ্যমান রয়েছে ${keepfiles[(I)filename]}যা ব্যবহার করে কোন মিল খুঁজে পাওয়া যায় না যদি 0 প্রদান করে:

 % print ${keepfiles[(I)foo]}
1
 % print ${keepfiles[(I)baz]}
0
 %

অ্যারেটিতে trueকোনও মিল নেই যদি ফিরে আসে এমন একটি ফাংশন তৈরি করতে আমরা এটি ব্যবহার করতে পারি $REPLY:

% nokeep() { (( ${keepfiles[(I)$REPLY]} == 0 )); }

অবশেষে, আমরা আমাদের কমান্ডের একটি যোগ্যতা হিসাবে এই ফাংশনটি ব্যবহার করি:

 % ls *(+nokeep)
baz  bazfoo  keepfiles.txt

বা, আপনার ক্ষেত্রে

 % rm -- *(+nokeep)

(আপনি সম্ভবত হোয়াইটলিস্ট ফাইলটির নামটি হোয়াইটলিস্টে যুক্ত করতে চাইবেন))


0

ধরে নিই যে আপনার ব্যাশ শেলটি চালু আছে extglob shopt, এখানে কিছুটা রক্ষণশীল বিকল্প রয়েছে:

rm !($(tr \\n \| < keep.txt))

(... সাথে বাগানবাড়ির অন্যথায় দুর্দান্ত কম পরামর্শ!)


0

যদি না আউটপুট ls /home/me/myfolder2tocleanup/অতিক্রম করে সর্বোচ্চ শেল যুক্তি সীমা ARG_MAX যা প্রায় 2MB উবুন্টু জন্য, আমি নিম্নলিখিত সুপারিশ করবে।


একটি ওয়ান লাইন কমান্ড বাস্তবায়ন যা কাজটি করবে, তা নীচে হবে:

  1. dont-delete.txtফাইলগুলি মুছে ফেলা ডিরেক্টরিটিতে ফাইলটি অনুলিপি করুন :
cp dont-delete.txt /home/me/myfolder2tocleanup/
  1. cd ফাইলগুলি ধারণকারী ডিরেক্টরিতে এভাবে মুছে ফেলা হবে:
cd /home/me/myfolder2tocleanup/
  1. কমান্ডটি পরীক্ষা করতে একটি শুকনো রান করুন এবং এটি ফাইলের নামগুলি মুছে ফেলুন যা এটি সনাক্ত করে যে সেগুলি মুছতে পারে না প্রকৃতপক্ষে এটি মোছা ছাড়াই:
ls -p | grep -v / | sed 's/\<dont-delete.txt\>//g' | sort | comm -3 - <(sort dont-delete.txt) | xargs echo | tr " " "\n"
  1. আপনি যদি আউটপুট নিয়ে সন্তুষ্ট হন তবে কমান্ডটি চালিয়ে ফাইলগুলি মুছুন:
ls -p | grep -v / | sed 's/\<dont-delete.txt\>//g' | sort | comm -3 - <(sort dont-delete.txt) | xargs rm

Explaination:

  • ls -pবর্তমান ডিরেক্টরিতে সমস্ত ফাইল এবং ডিরেক্টরি তালিকাবদ্ধ -pকরবে এবং বিকল্পটি /ডিরেক্টরিতে নামের সাথে যুক্ত হবে।
  • grep -v //নামের সাথে থাকা সমস্ত আইটেম সরিয়ে ডিরেক্টরিগুলি বাদ দেবে ।
  • sed 's/\<dont-delete.txt\>//g'dont-delete.txtফাইলটি বাদ দেবে , সুতরাং এটি প্রক্রিয়াতে মোছা হবে না।
  • sortকেবলমাত্র তা নিশ্চিত করার জন্য, এর বাকী আউটপুটটি বাছাই করুন ls
  • comm -3 - <(sort dont-delete.txt)dont-delete.txtফাইলটি বাছাই করবে , এর সাজানো আউটপুটটির সাথে তুলনা করে lsএবং উভয়টিতে থাকা ফাইলের নাম বাদ দেবে।
  • xargs rmইতিমধ্যে প্রক্রিয়াজাত আউটপুটটির বাকী সমস্ত ফাইল নাম সরিয়ে ফেলবে ls। সমস্ত বর্তমান ডিরেক্টরির মধ্যে আইটেম জন্য ব্যতীত সরানো হবে এই উপায়ে ডিরেক্টরি , তালিকাভুক্ত ফাইল dont-delete.txtফাইল এবং ফাইল নিজেইdont-delete.txt

শুকনো রান অংশে:

  • xargs echo অপসারণ করা উচিত ফাইল মুদ্রণ করবে।
  • tr " " "\n" সহজ পাঠযোগ্যতার জন্য স্পেসগুলি নতুন লাইনে অনুবাদ করবে।

0

আমি দৃ rsyncposted়ভাবে এখানে পোস্ট সমাধান ব্যবহার করার পরামর্শ দিচ্ছি ; অন্যথায় উল্লিখিত ব্যতিক্রমী শর্ত সহ নীচের সমাধানটি ব্যবহার করুন।

ধরে নিই যে আপনার ফাইলগুলিতে কোনও শ্বেত স্পেস (স্পেসস / ট্যাবস) নেই একটি ফাইলের তালিকাভুক্ত excludelist, তবে আপনি এটি করতে পারেন:

find /path/to -type f \( ! -name "excludelist" $(printf ' -a ! -name %s\n' $(< excludelist)) \)

শুধু যোগ -deleteউপরে ফাইল যা অস্তিত্ব নেই মুছে ফেলতে কমান্ড excludelist ফাইল। আপনার খোঁজ না থাকে -deleteবিকল্প আপনি ব্যবহার করতে পারেন rmসঙ্গে -execনিম্নলিখিত হিসাবে:

find /path/to -type f \( ! -name "excludelist" $(printf ' -a ! -name %s\n' $(< excludelist)) \) -exec echo rm {} \;

অথবা ব্যবহার -execসঙ্গে +টারমিনেটর পরিবর্তে।

find /path/to -type f \( ! -name "excludelist" $(printf ' -a ! -name %s\n' $(< excludelist)) \) -exec echo rm {} +

echo খালি শুকনো রান ব্যবহার করতে ব্যবহৃত হয়।


-1

আমার পরামর্শটি হ'ল:

sed -e 's/^/\.\//' dont-delete.txt > dont-delete-relative-path.txt
find . -type f -print | grep -Fxvf dont-delete-relative-path.txt | xargs -d'\n' rm

আপডেট 2018-08-07

উদাহরণ:

1: mkdir /tmp/delete-example && cd /tmp/delete-example
2: touch a b c d
3: echo "./a\n./b\n./dont-delete.txt\n" > dont-delete.txt
4: find . -type f -print | grep -Fxvf dont-delete.txt | xargs -d'\n' rm

লাইন 3 পরে নোট করুন আপনার dont-delete.txtলিখিত সামগ্রী সহ ফাইলটি পাবেন :

./a
./b
./dont-delete.txt

(নেতৃস্থানীয় ./হয় খুবই গুরুত্বপূর্ণ )

ফাইল cএবং dমুছে ফেলা হবে।


আমি এটি একটি নতুন লাইনের দ্বারা পৃথক করা ফাইলের নামের একটি পাঠ্য ফাইল দিয়ে চেষ্টা করেছি। এটি ডিরেক্টরিতে সমস্ত ফাইল মুছে ফেলা শেষ করে।
জ্যাকস ম্যালাপ্রাদে

আমার অনুমান যে আপনার "কিপ তালিকা" ভুল ছিল।
nyxz

আমি উদাহরণ ব্যবহার যোগ করেছি।
nyxz
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.