`Find`- এর নির্ধারিত বিকল্পটি বোঝা`


53

আমি নিজেকে নিয়মিত সিনট্যাক্স সন্ধান করছি

find . -name "FILENAME"  -exec rm {} \;

মূলত কারণ আমি দেখতে পাচ্ছি না যে -execঅংশটি ঠিক কীভাবে কাজ করে। ধনুর্বন্ধনী, ব্যাকস্ল্যাশ এবং সেমিকোলনের অর্থ কী? এই সিনট্যাক্সের জন্য কি অন্যান্য ব্যবহারের মামলা রয়েছে?


11
@ ফিলিপোস: আমি আপনার বক্তব্যটি দেখছি। দয়া করে মনে রাখবেন যে ম্যান পেজগুলি একটি রেফারেন্স, অর্থাত্ সিনট্যাক্সটি সন্ধান করার জন্য বিষয়টি বোঝার জন্য তাদের দরকারী। বিষয়টিতে নতুন কারও জন্য, তারা প্রায়শই ক্রিপ্টিক্যাল এবং আনুষ্ঠানিকভাবে ব্যবহারযোগ্য হয়ে উঠেন। আপনি দেখতে পাবেন যে স্বীকৃত উত্তরটি ম্যান পৃষ্ঠাতে প্রবেশের সময় হিসাবে প্রায় 10 গুণ বেশি এবং এটি একটি কারণ।
Zsolt Szilagy

6
এমনকি পুরাতন পসিক্সman পৃষ্ঠায় একটি ইউটিলিটি_নাম বা আর্গুমেন্ট কেবল দুটি অক্ষর "{containing" সমন্বিত বর্তমান প্যাথনাম দ্বারা প্রতিস্থাপন করা হবে যা আমার কাছে যথেষ্ট বলে মনে হয়। অতিরিক্ত প্রশ্ন এটির যেমন একটি উদাহরণ রয়েছে যেমন -exec rm {} \;ঠিক আপনার প্রশ্নের মতো। আমার দিনগুলিতে, "বড় ধূসর প্রাচীর" ব্যতীত অন্য কোনও সংস্থান ছিল, মুদ্রিত manপৃষ্ঠাগুলির বইগুলি (কাগজ সংরক্ষণের চেয়ে উত্তেজক ছিল)। সুতরাং আমি জানি যে বিষয়টিতে নতুন কারও পক্ষে এটি যথেষ্ট। যদিও আপনার শেষ প্রশ্নটি এখানে জিজ্ঞাসা করা মোটামুটি। দুর্ভাগ্যক্রমে @ কুসালানন্দ বা আমার কাছেই এর কোনও উত্তর নেই।
ফিলিপোস

1
কমোন @ ফিলিপোস। আপনি কি সত্যই কুসালানন্দকে বলছেন যে তিনি ম্যানপেজে উন্নতি করেননি? :-)
Zsolt Szilagy

1
@ অালো যদিও xargsকখনও কখনও সুবিধাজনক, findএটি ছাড়া কমান্ডের জন্য একাধিক পাথ আর্গুমেন্ট পাস করতে পারে। -exec command... {} +( +পরিবর্তে এর সাথে \;) command...যতগুলি ফিট হবে তার পরে যতগুলি পাথ পাস হবে (কমান্ড-লাইন কত দীর্ঘ হতে পারে তার উপর প্রতিটি ওএসের নিজস্ব সীমা থাকে)। আর মত xargs, +এর -terminated ফর্ম findএর -execঅ্যাকশনটি চালানো হবে command...একাধিক বার বিরল ক্ষেত্রে সীমা মধ্যে মাপসই অনেকগুলি পাথ আছে হবে।
এলিয়াহ কাগন

2
@ ZsoltSzilagy আমি এটি আগেও বলিনি বা এটির অর্থও নয়। তিনি আপনাকে খুব ভাল খাওয়াতে পেরেছিলেন, আমার মনে হয় আপনি নিজেই খাওয়ার জন্য যথেষ্ট বয়স্ক are (-;
ফিলিপোস

উত্তর:


90

এই উত্তরটি নিম্নলিখিত অংশে আসে:

  • এর বেসিক ব্যবহার -exec
  • -execসাথে সংমিশ্রণে ব্যবহার করাsh -c
  • ব্যবহার -exec ... {} +
  • ব্যবহার -execdir

এর বেসিক ব্যবহার -exec

-execবিকল্প তার আর্গুমেন্ট হিসাবে ঐচ্ছিক আর্গুমেন্ট সহ একটি বহিস্থিত ইউটিলিটি লাগে এবং সঞ্চালন করে।

যদি স্ট্রিং {}প্রদত্ত কমান্ডের যে কোনও জায়গায় উপস্থিত থাকে, তবে এর প্রতিটি উদাহরণ বর্তমানে প্রক্রিয়াকরণ হওয়া প্যাথনাম দ্বারা প্রতিস্থাপন করা হবে (উদাঃ ./some/path/FILENAME)। বেশিরভাগ শেলগুলিতে দুটি চরিত্রের {}উদ্ধৃতি দেওয়ার প্রয়োজন হয় না।

কমান্ড একটি দিয়ে শেষ করা হবে ;জন্য find(সেখানে আরও বিকল্প পরে হতে পারে) যেখানে জানতে এটা শেষ। ;শেল থেকে রক্ষা করতে , এটি হিসাবে \;বা হিসাবে উদ্ধৃত করা প্রয়োজন ';', অন্যথায় শেল এটি findকমান্ডের শেষ হিসাবে দেখবে ।

উদাহরণ ( \প্রথম দুটি লাইনের শেষে কেবল লাইন ধারাবাহিকতার জন্য):

find . -type f -name '*.txt'      \
   -exec grep -q 'hello' {} ';'   \
   -exec cat {} ';'

এটি সমস্ত নিয়মিত ফাইল ( -type f) যার নাম *.txtবর্তমান ডিরেক্টরিতে বা নীচে প্যাটার্নের সাথে মেলে । এরপরে এটি পরীক্ষা করে helloদেখা গেছে যে কোন স্ট্রিং ফাইল পাওয়া গিয়েছে তা ব্যবহার করে grep -q(যা কোনও আউটপুট উত্পাদন করে না, কেবলমাত্র একটি প্রস্থান স্থিতি)। স্ট্রিং ধারণ করে এমন ফাইলগুলির catজন্য টার্মিনালে ফাইলের সামগ্রীগুলি আউটপুট দিতে কার্যকর করা হবে।

প্রতিটি -execএছাড়াও pathnames দ্বারা পাওয়া একটি "পরীক্ষা" মত কাজ করে find, ঠিক এরকমই -typeএবং -nameআছে। যদি কমান্ডটি শূন্য প্রস্থান স্থিতি দেয় ("সাফল্য নির্দেশ করে), findকমান্ডের পরবর্তী অংশটি বিবেচনা করা হয়, অন্যথায় findকমান্ডটি পরবর্তী পথের নামের সাথে চালিয়ে যায়। এটি স্ট্রিং রয়েছে এমন ফাইলগুলি খুঁজে পেতে helloঅন্য সমস্ত ফাইল উপেক্ষা করার জন্য উপরের উদাহরণে ব্যবহৃত হয় is

উপরের উদাহরণটি দুটি সাধারণ ব্যবহারের ক্ষেত্রে চিত্রিত করে -exec:

  1. অনুসন্ধান আরও সীমাবদ্ধ করার পরীক্ষা হিসাবে।
  2. সন্ধানকারী পথের নামটিতে কোনও ধরণের ক্রিয়া সম্পাদন করা (সাধারণত, তবে findকমান্ডের শেষে প্রয়োজন হয় না )।

-execসাথে সংমিশ্রণে ব্যবহার করাsh -c

যে আদেশটি -execকার্যকর করতে পারে তা alচ্ছিক আর্গুমেন্ট সহ একটি বাহ্যিক ইউটিলিটিতে সীমাবদ্ধ। শেল বিল্ট-ইনগুলি, ফাংশন, শর্তসাপেক্ষ, পাইপলাইন, পুনর্নির্দেশগুলি ইত্যাদি সরাসরি ব্যবহার করা -execসম্ভব নয়, যদি না sh -cশিশু শেলের মতো কিছুতে আবৃত থাকে ।

যদি bashবৈশিষ্ট্যগুলি প্রয়োজন হয় তবে তার bash -cজায়গায় ব্যবহার করুন sh -c

sh -c/bin/shকমান্ড লাইনে প্রদত্ত স্ক্রিপ্ট দিয়ে চালায় , তারপরে সেই স্ক্রিপ্টে alচ্ছিক কমান্ড লাইন আর্গুমেন্ট।

sh -cনিজেই ব্যবহার করার একটি সাধারণ উদাহরণ find:

sh -c 'echo  "You gave me $1, thanks!"' sh "apples"

এটি শিশু শেল স্ক্রিপ্টে দুটি আর্গুমেন্ট পাস করে:

  1. স্ট্রিং sh। এটি $0স্ক্রিপ্টের অভ্যন্তরের মতোই উপলব্ধ হবে এবং যদি অভ্যন্তরীণ শেলটি একটি ত্রুটি বার্তা আউটপুট করে তবে এটি এই স্ট্রিংটির সাথে এটি উপসর্গ করবে।

  2. যুক্তি applesহিসাবে পাওয়া যায় $1লিপিতে, এবং আরো আর্গুমেন্ট, তবে এই হিসাবে উপলব্ধ হতো হয়েছে $2, $3ইত্যাদি তারা তালিকায় পাওয়া যাবে "$@"(-setup জন্য $0যার অংশ হবে না "$@")।

এই সঙ্গে একযোগে দরকারী -execকরুন কারণ এটি আমাদের ইচ্ছামত জটিল স্ক্রিপ্ট pathnames দ্বারা পাওয়া উপর কাজ করে করতে পারবেন find

উদাহরণ: নির্দিষ্ট ফাইলের প্রত্যয়যুক্ত সমস্ত নিয়মিত ফাইল সন্ধান করুন এবং সেই ফাইলের প্রত্যয়টি অন্য কয়েকটি প্রত্যয়তে পরিবর্তন করুন, যেখানে প্রত্যয়গুলি ভেরিয়েবলগুলিতে রাখা হয়েছে:

from=text  #  Find files that have names like something.text
to=txt     #  Change the .text suffix to .txt

find . -type f -name "*.$from" -exec sh -c 'mv "$3" "${3%.$1}.$2"' sh "$from" "$to" {} ';'

অভ্যন্তরীণ স্ক্রিপ্ট ভিতরে, $1স্ট্রিং হতে হবে text, $2স্ট্রিং হতে হবে txtএবং $3যাই হোক না কেন পথনাম হবে findআমাদের জন্য পাওয়া গেছে। প্যারামিটার সম্প্রসারণ ${3%.$1}পথটির নাম নেবে এবং এ .textথেকে প্রত্যয়টি সরিয়ে ফেলবে ।

অথবা, dirname/ ব্যবহার করে basename:

find . -type f -name "*.$from" -exec sh -c '
    mv "$3" "$(dirname "$3")/$(basename "$3" ".$1").$2"' sh "$from" "$to" {} ';'

বা, অভ্যন্তরীণ স্ক্রিপ্টে যুক্ত ভেরিয়েবলগুলি সহ:

find . -type f -name "*.$from" -exec sh -c '
    from=$1; to=$2; pathname=$3
    mv "$pathname" "$(dirname "$pathname")/$(basename "$pathname" ".$from").$to"' sh "$from" "$to" {} ';'

নোট করুন যে এই শেষ প্রকরণের মধ্যে, বহিরাগত স্ক্রিপ্টের একই নামগুলির সাথে ভেরিয়েবলগুলি fromএবং toচাইল্ড শেলের মধ্যে ভেরিয়েবলগুলি থেকে পৃথক।

উপরে থেকে একটি অবাধ জটিল স্ক্রিপ্ট কলিং সঠিক পথ -execসঙ্গে findfindমত একটি লুপ ব্যবহার

for pathname in $( find ... ); do

ত্রুটি প্রবণ এবং অবহেলিত (ব্যক্তিগত মতামত)। এটি হোয়াইটস্পেসে ফাইলের নামগুলি বিভক্ত করছে, ফাইলের নাম গ্লোব্বিং করছে, এবং findলুপের প্রথম পুনরাবৃত্তি চালানোর আগে শেলটিকে পুরো ফলাফলটি প্রসারিত করতে বাধ্য করে ।

আরো দেখুন:


ব্যবহার -exec ... {} +

;শেষে দ্বারা প্রতিস্থাপিত হতে পারে +। এটি findপ্রতিটি প্রাপ্ত পাথের নামের চেয়ে একবারের চেয়ে যতগুলি আর্গুমেন্ট (পাথের নাম পাওয়া গেছে) দিয়ে প্রদত্ত কমান্ডটি কার্যকর করতে পারে। স্ট্রিংটি {} এটি +কাজ করার জন্য ঠিক আগে ঘটতে হবে

find . -type f -name '*.txt' \
   -exec grep -q 'hello' {} ';' \
   -exec cat {} +

এখানে, findফলস্বরূপ পাথের নামগুলি সংগ্রহ করা হবে এবং catএকবারে যতগুলি সম্ভব সম্ভবকে কার্যকর করা হবে।

find . -type f -name "*.txt" \
   -exec grep -q "hello" {} ';' \
   -exec mv -t /tmp/files_with_hello/ {} +

একইভাবে এখানে, mvযতবার সম্ভব কার্যকর করা হবে। এই শেষ উদাহরণটির জন্য mvকোর্টিলগুলি (যা -tবিকল্পটিকে সমর্থন করে ) থেকে জিএনইউ প্রয়োজন ।

-exec sh -c ... {} +ইচ্ছামত জটিল স্ক্রিপ্টের সাহায্যে প্যাথনামগুলির একটি সেট লুপ করার একটি কার্যকর উপায় Using

বেসিকগুলি ব্যবহার করার সময় একই রকম -exec sh -c ... {} ';', তবে স্ক্রিপ্টটি এখন আর্গুমেন্টগুলির অনেক বেশি দীর্ঘ তালিকা গ্রহণ করে। "$@"স্ক্রিপ্টের ভিতরে লুপ করে এগুলি লুপ করা যায় ।

ফাইলের নাম প্রত্যয় পরিবর্তন করে এমন সর্বশেষ বিভাগ থেকে আমাদের উদাহরণ:

from=text  #  Find files that have names like something.text
to=txt     #  Change the .text suffix to .txt

find . -type f -name "*.$from" -exec sh -c '
    from=$1; to=$2
    shift 2  # remove the first two arguments from the list
             # because in this case these are *not* pathnames
             # given to us by find
    for pathname do  # or:  for pathname in "$@"; do
        mv "$pathname" "${pathname%.$from}.$to"
    done' sh "$from" "$to" {} +

ব্যবহার -execdir

এছাড়াও রয়েছে -execdir(বেশিরভাগ findরূপগুলি দ্বারা প্রয়োগ করা হয় তবে মানক বিকল্প নয়)।

এটি -execপ্রদত্ত শেল কমান্ডটি তার বর্তমান কার্যকরী ডিরেক্টরি হিসাবে {}পাওয়া পাথের findনামের ডিরেক্টরিতে কার্যকর করা হয় এবং এটিতে কোনও পাথ ছাড়াই পাওয়া পথের বেসনামটি থাকবে (তবে জিএনইউ এখনও বেসনটির সাথে পূর্ব নামটি উপস্থাপন করবে) ./, বিএসডি সহ findএটা করবে না)।

উদাহরণ:

find . -type f -name '*.txt' \
    -execdir mv {} done-texts/{}.done \;

এটি প্রতিটি পাওয়া ফাইল-ফাইল একই ডিরেক্টরিতে*.txt প্রাক-বিদ্যমান done-textsসাব - ডিরেক্টরিতে স্থানান্তরিত করবে যেখানে ফাইলটি পাওয়া গেছে । এতে প্রত্যয় যুক্ত করে ফাইলটিরও নামকরণ .doneকরা হবে।

এটি করা একটু কৌশলযুক্ত -execহবে কারণ ফাইলটির {}নতুন নাম তৈরি করতে আমাদের খুঁজে পাওয়া ফাইলটির বেসনামটি বের করতে হবে। ডিরেক্টরিটি সঠিকভাবে {}সনাক্ত করতে আমাদের কাছ থেকে ডিরেক্টরি নামও প্রয়োজন done-texts

এর সাথে এ জাতীয় -execdirকিছু জিনিস সহজ হয়ে যায়।

-execপরিবর্তে ব্যবহার করে সংশ্লিষ্ট অপারেশন -execdirএকটি শিশু শেল নিয়োগ করতে হবে:

find . -type f -name '*.txt' -exec sh -c '
    for name do
        mv "$name" "$( dirname "$name" )/done-texts/$( basename "$name" ).done"
    done' sh {} +

বা,

find . -type f -name '*.txt' -exec sh -c '
    for name do
        mv "$name" "${name%/*}/done-texts/${name##*/}.done"
    done' sh {} +

7
-execএকটি প্রোগ্রাম নেয় এবং তর্ক করে এবং এটি চালায়; কিছু শেল কমান্ড কেবল একটি প্রোগ্রাম এবং যুক্তি নিয়ে গঠিত তবে অনেকগুলি তা করে না। একটি শেল কমান্ড পুনর্নির্দেশ এবং পাইপ অন্তর্ভুক্ত করতে পারে; -execপারবেন না (যদিও findপুরোটি পুনঃনির্দেশিত করা যেতে পারে)। একটি শেল কমান্ড ; && ifইত্যাদি ব্যবহার করতে পারে ; -execনা, যদিও -a -oকিছু করতে পারে। একটি শেল কমান্ড একটি উপাধি বা শেল ফাংশন, বা বিল্টিন হতে পারে; -execনা পারেন. একটি শেল কমান্ড vars প্রসারিত করতে পারে; -execপারবেন না (যদিও বাইরের শেলটি ক্যান চালায় find) একটি শেল কমান্ড $(command)প্রতিটি সময় পৃথক পৃথক করতে পারে ; -execনা পারেন. ...
dave_thompson_085

... একটি শেল কমান্ড গ্লোব করতে -execপারে , পারে না - যদিও findবেশিরভাগ গ্লোব যেমন ফাইলে পুনরাবৃত্তি করতে পারে, তাই এটি খুব কমই চাইত।
dave_thompson_085

@ dave_thompson_085 অবশ্যই, শেল কমান্ড shনিজেই হতে পারে, যা সমস্ত কিছু করার সম্পূর্ণভাবে সক্ষম
তাভিয়ান বার্নস

2
এখানে শেল কমান্ডটি ভুল বলা হচ্ছে, find -exec cmd arg \;শেল কমান্ড লাইনের ব্যাখ্যার জন্য শেলকে ডাকে না, এটি execlp("cmd", "arg")সরাসরি চলে, না execlp("sh", "-c", "cmd arg")(যার জন্য শেলটি বিল্টিন না execlp("cmd", "arg")থাকলে সমান সমাপ্ত হবে cmd)।
স্টাফেন চেজেলাস

2
আপনি শোধন করতে পারে যে সব findআর্গুমেন্ট পরে -execএবং পর্যন্ত ;বা +তার আর্গুমেন্ট সহ চালানো, একটি প্রতিটি নিদর্শনের সঙ্গে কমান্ড আপ করতে {}যুক্তি বর্তমান ফাইল (সঙ্গে দিয়ে প্রতিস্থাপিত ;), এবং {}গত যুক্তি আগের মতোই +ফাইলগুলির একটি তালিকা দিয়ে প্রতিস্থাপিত পৃথক যুক্তি হিসাবে ( {} +ক্ষেত্রে)। আইওউ বেশ কয়েকটি যুক্তি -execগ্রহণ করে যা একটি বা দ্বারা সমাপ্ত হয় । ;{} +
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.