আমি কীভাবে মার্জিত উপায়ে সাবফোল্ডারগুলিতে একটি নির্দিষ্ট এক্সটেনশন সহ সমস্ত ফাইলগুলিতে একটি ক্রিয়া সম্পাদন করব?


18

আমার বর্তমান সেরা বেটটি হ'ল:

for i in $(find . -name *.jpg); do echo $i; done

সমস্যা: ফাইলের নামগুলিতে ফাঁকা স্থান পরিচালনা করে না।

দ্রষ্টব্য: আমি এটি করার একটি গ্রাফিকাল পদ্ধতিও পছন্দ করব, যেমন "ট্রি" কমান্ড।


আপনি কি সহজেই চারপাশে উদ্ধৃতি রাখতে পারবেন না $i? আমি এটি করি এবং এটি ভাল কাজ করে। এই পদ্ধতির সাথে কিছু ভুল আছে?
উমর ফারুক খাজা

উত্তর:


26

ক্যানোনিকাল উপায় হয়

find . -name '*.jpg' -exec echo {} \;

( একাধিক ফাইল পাস \;করার +জন্য প্রতিস্থাপন করুনecho )

বা (জিএনইউ সুনির্দিষ্ট, যদিও কিছু বিএসডি এখন রয়েছে):

find . -name '*.jpg' -print0 | xargs -r0 echo

zsh:

for i (**/*.jpg(D)) echo $i

2
আপনি যদি xargs -0 ব্যবহার করে থাকেন তবে এটির সাথে
ফাইন্ড

1
@ মাইকেলKjörling, কোন উদ্ধৃতি {no কোন পার্থক্য করে না। find find অনুসন্ধান দ্বারা প্রসারিত হয়, শেল নয়। উন্নতি echoহ'ল ব্যবহারের মতো নয় যা পালানোর ক্রমগুলি \b(কমপক্ষে ইউনিক্স কনফরমেন্টস echo) এর মতো প্রসারিত করে ।
স্টাফেন চ্যাজেলাস

1
আপনি কি নিশ্চিত? findর manpage শো find . -type f -exec file '{}' \;মধ্যে EXAMPLESঅধ্যায়। সম্ভবত কিছু শাঁস বিশেষত ধনুর্বন্ধনী আচরণ করবে।
কাসারডনকি

1
উদ্ধৃতিগুলি ক্ষতি করে না তবে কোনও পার্থক্য নেই। সকল '{}', \{\}, {}, "{}", '{'}শেল (যাই হোক না কেন বোর্ন মত শেল) দ্বারা একটি আর্গুমেন্ট যে দুই অক্ষর খুঁজে পেতে "{" এবং "}" সম্প্রসারিত করছে। "প্রতিধ্বনি" এর সাথে "অনুসন্ধান" প্রতিস্থাপন করুন, বা printf '<%s>\n' findআপনি যদি ডাবল-চেক করতে চান তবে।
স্টাফেন চেজেলাস


2

ইতিমধ্যে আরও ভাল উত্তর দেওয়া হয়েছে।

তবে মনে রাখবেন যে কোডগুলি আপনি দিয়েছেন তাতে শূন্যস্থানই কেবল সমস্যা নয়। ট্যাব, নিউলাইন এবং ওয়াইল্ডকার্ড অক্ষরগুলিও একটি সমস্যা।

সঙ্গে

IFS='
'
set -f
for i in $(find . -name '*.jpg'); do echo "$i"; done

তারপরে কেবল নিউলাইন চরিত্রগুলিই একটি সমস্যা।


1

আপনি ফাইলটির নাম পড়ার চেষ্টা করার সময় লোকেরা যে সমস্যার মুখোমুখি হয় সেগুলির মধ্যে একটি যা আপনি উল্লেখ করেছেন। কখনও কখনও, সীমিত জ্ঞানযুক্ত এবং ফাইল এবং ফোল্ডার কাঠামোর ভুল ধারণা থাকা লোকেরা " ইউনিক্স ইন সব কিছু একটি ফাইল " ভুলে যাওয়ার প্রবণতা পোষণ করে । সুতরাং তারা বুঝতে পারে না যে পাশাপাশি ফাঁকা স্থানগুলিও তাদের হ্যান্ডেল করা দরকার, কারণ ফাইলের নামটিতে স্পেস সহ 2 বা ততোধিক শব্দ থাকতে পারে।

সমাধান: সুতরাং এটি করার আরও একটি ভাল উপায় হল একটি পরিষ্কার পড়া

আমরা এখানে উপস্থিত সমস্ত ফাইলগুলি পড়ব এবং এগুলি একটি ভেরিয়েবলে রাখব, পরের বার যখন কাঙ্ক্ষিত প্রসেসিং করা হয় তখন আমাদের কেবলমাত্র সেই পরিবর্তনশীল কোটের ভিতরে রাখতে হবে যা ফাইলগুলির নাম ফাঁকা রেখে সংরক্ষণ করবে। এটি করার একটি প্রাথমিক উপায় এটি, তবে এখানকার অন্যান্য লোকদের দেওয়া অন্যান্য উত্তরগুলি ঠিক সেইভাবে কাজ করে।

লিপি :

 find /path/to/files/ -iname "*jpg" | \
  while read I; do
   cp -v --parent "$I" /backup/dir/
  done

এখানে আমি ফাইলগুলিকে তাদের পাথ দিয়ে পাঠ করছি এবং যা কিছু পড়ছি তা আমি তাদের একটি ভেরিয়েবলের মধ্যে রেখে দিচ্ছি, যা আমি স্থানটি সংরক্ষণের জন্য এটি প্রক্রিয়া করার সময় পরবর্তী সময়ে উদ্ধৃত করব যাতে এটি সঠিকভাবে প্রক্রিয়া করা যায়।

আশা করি এটি আপনাকে কোনওভাবে সহায়তা করবে।


1
"সবকিছুই একটি ফাইল" বলতে অন্য কিছু বোঝায়। আপনার সমাধানটি জিএনইউ নির্দিষ্ট and এবং ফাইলের নামগুলিতে ব্যাকস্ল্যাশ বা নিউলাইন অক্ষরগুলির সাথে লড়াই করে না। "পড়ার সময়" শেলগুলিতে লুপগুলি (আইএমও) প্রায়শই খারাপ শেল স্ক্রিপ্টিং অনুশীলনের ইঙ্গিত দেয়।
স্টাফেন চেজেলাস

@ এসসিএইচ: হু, এবং আমি ভাবতাম, এটা ঠিক আছে। এটি নির্দেশ করার জন্য ধন্যবাদ। আমার সম্ভবত এটি আরও দেখার প্রয়োজন।
ডার্ক নাইট

দুঃখিত, আমি "জিএনইউ" বলতে চাইছি, উপরের "জিএনএন" নয় (এটি আমি প্রথম উপলব্ধি করেছি যে এগুলি এনজিগ্রাম বিটিডাব্লু ...)
স্টাফেন চ্যাজেলাস

1

কেবল সাথে findএবং bash:

find . -name '*.jpg' -exec bash -c '
    echo "treating file $1 in bash, from path : ${1%/*}" 
' -- {} \;

এইভাবে, আমরা ব্যবহার করি $1 কোনও বেসিক স্ক্রিপ্টের মতো ব্যাশে যা কোনও উন্নত (বা না) কার্য সম্পাদন করার জন্য সুন্দর দৃষ্টিভঙ্গি খোলে।

আরও কার্যকর উপায় (প্রতিটি ফাইলের জন্য নতুন বাশ শুরু করা এড়াতে):

find . -name '*.jpg' -exec bash -c 'for i do
    echo "treating file $i in bash, from path : ${i%/*}" 
  done' -- {} +

0

ব্যাশের সাম্প্রতিক সংস্করণে, আপনি globstarবিকল্পটি ব্যবহার করতে পারেন :

shopt -s globstar
for file in **/*.jpg ; do
    echo "$file"
done

সাধারণ ক্রিয়াগুলির জন্য, আপনি এমনকি লুপটি পুরোপুরি এড়িয়ে যেতে পারেন:

echo **/*.jpg

যেটি zsh- এ কাজ করে (যেখানে বৈশিষ্ট্যটি উদ্ভূত হয়েছিল) এবং ksh93 (সহ set -G) দিয়ে, এটি ব্যাশ ব্যবহার করা উচিত নয় কারণ বাশ সংস্করণটি মূলত ভাঙা হয় (ঠিক জিএনইউ এর মতো grep -r) এটি ডিরেক্টরিতে চিহ্নগুলির ( যেমন সমেত find -Lবা zsh এর সমতুল্য) নেমে আসে ***/*.jpg)। এছাড়াও এটি লক্ষ্য করুন যে এটির বিপরীতে এটি ডটফায়ালগুলি বাদ দেবে এবং ডটডিয়ারে নেমে যাবে না (ডিফল্টরূপে)।
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.