ইউনিক্স: একটি ফাইলের তালিকাভুক্ত ফাইলগুলি কীভাবে মুছবেন


92

আমি মুছতে চাইছি এমন ফাইলের মুখোশগুলির তালিকা সহ আমার একটি দীর্ঘ পাঠ্য ফাইল রয়েছে

উদাহরণ:

/tmp/aaa.jpg
/var/www1/*
/var/www/qwerty.php

আমার সেগুলি মুছতে হবে। Rm `cat 1.txt` ব্যবহার করে চেষ্টা করা হয়েছে এবং এটি বলেছে তালিকাটি খুব দীর্ঘ।

এই কমান্ডটি খুঁজে পেয়েছে, তবে আমি তালিকা থেকে ফোল্ডারগুলি পরীক্ষা করে দেখছি, তাদের মধ্যে এখনও কিছু ফাইল রয়েছে xargs rm <1.txtম্যানুয়াল আরএম কল এই জাতীয় ফোল্ডারগুলি থেকে ফাইলগুলি সরিয়ে দেয়, সুতরাং অনুমতি নিয়ে কোনও সমস্যা নেই।


8
যদিও এটি ছয় বছর পরে: আপনি কি উত্তরগুলির কোনও একটি মানা করবেন না? এটি প্রশ্নটিকে সমাধান করা হিসাবে চিহ্নিত করবে এবং অন্যান্য ব্যবহারকারীদেরও সহায়তা করবে।
মেরোস

উত্তর:


114

এটি খুব দক্ষ নয়, তবে যদি আপনার গ্লোব নিদর্শনগুলির প্রয়োজন হয় তবে (কাজেই / var / www / * হিসাবে) কাজ করবে

for f in $(cat 1.txt) ; do 
  rm "$f"
done

যদি আপনার কোনও নিদর্শন না থাকে এবং আপনি নিশ্চিত হন যে ফাইলে আপনার পাথগুলিতে শ্বেত স্পেস বা অন্যান্য অদ্ভুত জিনিস রয়েছে না তবে আপনি xargs এর মতো ব্যবহার করতে পারেন:

xargs rm < 1.txt

4
পথে যদি কোনও স্থান থাকে তবে প্রথম সমাধান (সিএটি ব্যবহার করে) কী হবে?
a.dibacco

58

ধরে নিচ্ছি যে ফাইলগুলির তালিকা ফাইলটিতে রয়েছে 1.txt, তারপরে এটি করুন:

xargs rm -r <1.txt

-rবিকল্প নাম কোনো ডিরেক্টরি মধ্যে পুনরাবৃত্তির কারণ 1.txt

যদি কোনও ফাইল কেবল পঠনযোগ্য -fহয় তবে মুছতে বাধ্য করার জন্য বিকল্পটি ব্যবহার করুন :

xargs rm -rf <1.txt

প্রোগ্রামেটিক ডিলিটগুলি করে এমন কোনও সরঞ্জামের ইনপুট নিয়ে সতর্ক হন । করুন নির্দিষ্ট যে ইনপুট ফাইলে নামে ফাইল সত্যিই মুছে যেতে চলেছে। আপাতদৃষ্টিতে সহজ টাইপগুলি সম্পর্কে বিশেষত যত্নবান হন। উদাহরণস্বরূপ, আপনি যদি কোনও ফাইল এবং এর প্রত্যয়ের মধ্যে একটি স্থান প্রবেশ করেন তবে এটি দুটি পৃথক ফাইলের নাম হিসাবে উপস্থিত হবে:

file .txt

আসলে দুটি পৃথক ফাইল: fileএবং .txt

এটি এত বিপজ্জনক বলে মনে হচ্ছে না, তবে টাইপও যদি এরকম কিছু হয়:

myoldfiles *

তারপরে শুরু হওয়া সমস্ত ফাইল মোছার পরিবর্তে myoldfilesআপনি বর্তমান ডিরেক্টরিতে মুছে ফেলা myoldfilesএবং সমস্ত নন-ডট-ফাইল এবং ডিরেক্টরিগুলি শেষ করবেন। সম্ভবত আপনি যা চেয়েছিলেন তা নয়।


4
"মাইল্ডফিলস /" বা "/ টিএমপি" -আরএফ এর সাথে আরও বিপর্যয়কর। "/" এর পাশের স্থানের অক্ষরটি নোট করুন।
রায়

24

এটা ব্যবহার কর:

while IFS= read -r file ; do rm -- "$file" ; done < delete.list

আপনার যদি গ্লোব সম্প্রসারণের প্রয়োজন হয় তবে আপনি উদ্ধৃতিগুলি বাদ দিতে পারেন $file:

IFS=""
while read -r file ; do rm -- $file ; done < delete.list

তবে আপনাকে সাবধান করে দিন যে ফাইলের নামগুলিতে "সমস্যাযুক্ত" সামগ্রী থাকতে পারে এবং আমি উদ্ধৃত সংস্করণটি ব্যবহার করব। ফাইলটিতে এই প্যাটার্নটি কল্পনা করুন

*
*/*
*/*/*

এটি বর্তমান ডিরেক্টরি থেকে অনেক মুছে ফেলবে! আমি আপনাকে এমনভাবে মুছে ফেলা তালিকাটি প্রস্তুত করতে উত্সাহিত করব যাতে গ্লোব নিদর্শনগুলির আর প্রয়োজন হয় না এবং তারপরে আমার প্রথম উদাহরণের মতো উদ্ধৃতি ব্যবহার করুন


4
এটি বর্তমানে শুধুমাত্র উত্তর যে হ্যান্ডলগুলি সব /My Dir With Spaces/ /Spaces and globs/*.txt, --file-with-leading-dashesএবং একটি বোনাস এটি জিএনইউ / লিনাক্স, MacOS ও বাসদের উপর POSIX এবং কাজ করে যায়।
সে অন্য লোক 18

17

নতুন লাইন চরিত্রটিকে ডিলিমিটার হিসাবে সংজ্ঞায়িত করার জন্য আপনি '\ n' ব্যবহার করতে পারেন।

xargs -d '\n' rm < 1.txt

-আরএফ-এর সাথে সাবধান হন কারণ এটি যদি 1.txt ফাঁকা জায়গার সাথে থাকে তবে আপনি যা চান না তা মুছে ফেলতে পারে। এই কারণেই নতুন লাইন ডিলিমিটারটি কিছুটা নিরাপদ।

বিএসডি সিস্টেমে আপনি নতুন লাইন অক্ষরগুলি এর মতো ডিলিমিটার হিসাবে ব্যবহার করতে -0 বিকল্পটি ব্যবহার করতে পারেন:

xargs -0 rm < 1.txt

4
ওএস এক্স-এ এটি আমাকে পেয়ে যায়xargs: illegal option -- d
ওয়ালেডিরিয়াস

ভাল যুক্তি. দেখে মনে হচ্ছে -0ওএস এক্স ব্যতীত অন্য কোনও বিকল্প নেই
রে

4
xargs -I_ rm _এছাড়াও OS X এর কাজ করে :) দেখতে stackoverflow.com/a/39335402/266309
waldyrious

বিএসডি xargs ব্যবহার করে (যেখানে নেই -d), আপনি প্রথমে tr '\n' '\0' < 1.txt | xargs -0 rm
নিউলাইনগুলি নালিতে

14

আপনি এই ওয়ান-লাইনারটি ব্যবহার করতে পারেন:

cat 1.txt | xargs echo rm | sh

যা শেল সম্প্রসারণ করে rmতবে সর্বনিম্ন সংখ্যা কার্যকর করে।


যতো দিন কোনও প্রসারণ খুব বেশি দীর্ঘ হয় না?
ডগলাস লিডার

4
সত্য, কোনও গ্লোব একটি আর্গুমেন্টের তালিকা তৈরি করতে পারে যা খুব দীর্ঘ - আপনি প্রতিটি আরএম-তে পাস হওয়া আর্গুমেন্টের সংখ্যা কমাতে -n <n>যুক্তি যুক্ত করতে পারেন xargs, তবে এটি আপনাকে সীমা ছাড়িয়ে যাওয়া কোনও একক গ্লোব থেকে রক্ষা করবে না।
tgdavies

13

xargs -I{} sh -c 'rm {}' < 1.txtআপনি যা চান তা করা উচিত এই কমান্ডটি সম্পর্কে সতর্কতা অবলম্বন করুন কারণ সেই ফাইলটিতে একটি ভুল প্রবেশের ফলে অনেক সমস্যার সৃষ্টি হতে পারে।

এই উত্তরটি সম্পাদনা করা হয়েছিল পরে @ ডিভিডিগুলি উল্লেখ করে যে আসলটি শেল সম্প্রসারণ করে না।


ধন্যবাদ, তবে ফোল্ডারগুলি মুছতে হবে না, কেবল ফাইলগুলি
আলেকজান্ডার

4
গ্লোবগুলি প্রসারিত হবে না, কারণ শেলের মাধ্যমে সেগুলি কখনও দেখা যায় না।
tgdavies

@ স্টাফিজ ওয়া - আপনি ঠিক বলেছেন এই কমান্ডটি (কিছুটা কৃপণকর হলেও) কাজ করবে:xargs -I{} sh -c 'rm {}' < 1.txt
মার্ক ড্রাগো

4

এই বিশেষ ক্ষেত্রে, অন্যান্য উত্তরে উদ্ধৃত বিপদগুলির কারণে, আমি তা করব

  1. যেমন সম্পাদনা করুন ভিম এবং :%s/\s/\\\0/g, ব্যাকস্ল্যাশ সহ সমস্ত স্থানের অক্ষরগুলি পালিয়ে।

  2. তারপরে :%s/^/rm -rf /, কমান্ডটি প্রিপেন্ড করা হচ্ছে। সঙ্গে -rতোমার পরে ফাইল তাতে থাকা তালিকাভুক্ত ডিরেক্টরি আছে চিন্তা করতে হবে না, এবং -fএটা অনুপস্থিত ফাইল বা অনুরূপ এন্ট্রি কারণে অভিযোগ করা হবে না।

  3. সমস্ত কমান্ড চালান: $ source 1.txt


স্পেসগুলি কেবলমাত্র অক্ষর নয় যা পালানোর দরকার হয় না, ফাইল নামগুলিতে জনপ্রিয় হ'ল যে কোনও ধরণের বন্ধনী যা অবাঞ্ছিত প্রসার ঘটাতে পারে।
emk2203

4

cat 1.txt | xargs rm -f | bash কমান্ডটি রান করুন কেবল ফাইলগুলির জন্য নিম্নলিখিতগুলি করবে।

cat 1.txt | xargs rm -rf | bash কমান্ড রান করুন নিম্নলিখিত পুনরাবৃত্ত আচরণ করতে হবে।


2

অন্য কোনও উপায়ে দেওয়ার জন্য, আপনি নিম্নলিখিত কমান্ডটি সহজভাবে ব্যবহার করতে পারেন

$ cat to_remove
/tmp/file1
/tmp/file2
/tmp/file3
$ rm $( cat to_remove )

1

এখানে আরও একটি লুপিং উদাহরণ। এন্ট্রি একটি 'ফাইল' (বা উদাহরণস্বরূপ একটি 'ডিরেক্টরি') কিনা তা পরীক্ষা করে দেখার জন্য উদাহরণ হিসাবে এটিতে একটি 'if-বিবৃতি' রয়েছে:

for f in $(cat 1.txt); do if [ -f $f ]; then rm $f; fi; done

0

এখানে আপনি মুছে ফেলুন.টেক্সট থেকে ফোল্ডারগুলির সেটও ব্যবহার করতে পারেন যখন কিছু নিদর্শন এড়ানো যায়

foreach f (cat deletelist.txt)
    rm -rf ls | egrep -v "needthisfile|*.cpp|*.h"
end

0

এটি ফাইলের নামগুলিকে ফাঁকা স্থান দেওয়ার অনুমতি দেবে (পুনরায় উত্পাদনযোগ্য উদাহরণ)।

# Select files of interest, here, only text files for ex.
find -type f -exec file {} \; > findresult.txt
grep ": ASCII text$" findresult.txt > textfiles.txt
# leave only the path to the file removing suffix and prefix
sed -i -e 's/:.*$//' textfiles.txt
sed -i -e 's/\.\///' textfiles.txt

#write a script that deletes the files in textfiles.txt
IFS_backup=$IFS
IFS=$(echo "\n\b")
for f in $(cat textfiles.txt); 
do 
rm "$f"; 
done
IFS=$IFS_backup

# save script as "some.sh" and run: sh some.sh

0

যদি কেউ ওয়াইল্ডকার্ড সম্প্রসারণ ছাড়াই পছন্দ করে sedএবং সরিয়ে দেয় :

sed -e "s/^\(.*\)$/rm -f -- \'\1\'/" deletelist.txt | /bin/sh

অনুস্মারক: ফাইলটিতে নিখুঁত পাঠ্যনাম ব্যবহার করুন বা নিশ্চিত করুন যে আপনি সঠিক ডিরেক্টরিতে আছেন।

এবং সম্পূর্ণতার জন্য একই সাথে awk:

awk '{printf "rm -f -- '\''%s'\''\n",$1}' deletelist.txt | /bin/sh

যদি একক উদ্ধৃতিগুলি সরানো হয় তবে ওয়াইল্ডকার্ড সম্প্রসারণ কাজ করবে তবে ফাইলনেমে ফাঁকা স্থান থাকতে পারে তবে এটি বিপজ্জনক। এর জন্য ওয়াইল্ডকার্ডগুলির চারপাশে উদ্ধৃতি যুক্ত করা দরকার।

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