একাধিক কমান্ডের সাথে সন্ধান করুন


429

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

find *.txt -exec echo "$(tail -1 '{}'),$(ls '{}')" \;

মূলত, আমি বর্তমান ডিরেক্টরিটিতে প্রতিটি txt ফাইলের শেষ লাইনটি প্রিন্ট করার চেষ্টা করছি এবং লাইনের শেষে মুদ্রণ করার চেষ্টা করছি, ফাইলের নাম অনুসারে একটি কমা।



1
যতক্ষণ না কমান্ডের সম্ভাবনার সন্ধান করা যায়, আপনি কি এটি আপনার সিস্টেমে চেষ্টা করে দেখেননি?
শ্রীরাম

1
থেকে findম্যানুয়াল পৃষ্ঠা: There are unavoidable security problems surrounding use of the -exec option; you should use the -execdir option instead.unixhelp.ed.ac.uk/CGI/man-cgi?find
JVE999


@ JVE999 লিঙ্কটি ভাঙা হয়েছে, বিকল্প ss64.com/bash/find.html
কিথ এম

উত্তর:


657

find-execকমান্ডে একাধিক অংশ গ্রহণ করে । উদাহরণ স্বরূপ:

find . -name "*.txt" -exec echo {} \; -exec grep banana {} \;

নোট করুন যে এই ক্ষেত্রে দ্বিতীয় কমান্ড কেবল তখনই চালিত হবে যখন প্রথম ক্যালব সফলভাবে ফিরে আসবে, @ কালেব দ্বারা উল্লিখিত হিসাবে। যদি আপনি উভয় কমান্ডই তাদের সাফল্য বা ব্যর্থতা নির্বিশেষে চালিত করতে চান তবে আপনি এই নির্মাণটি ব্যবহার করতে পারেন:

find . -name "*.txt" \( -exec echo {} \; -o -exec true \; \) -exec grep banana {} \;

কিভাবে দুইবার গ্রেপ? এটি ব্যর্থ হচ্ছে: সন্ধান করুন / -exec egrep -i "my_string" {} \;
রাজীব

51
@ রাজিভ দ্বিতীয় এক্সিকিউটর কেবল তখনই চালিত হবে যখন প্রথম রিটার্ন সাফল্যের জন্য রিটার্ন কোডটি অন্যথায় এটি বাদ দেওয়া হবে। এটি সম্ভবত এই উত্তরে লক্ষ করা উচিত।
কালেব

1
এটি উত্তর হবে
পাইওভার

1
-nপ্রতিধ্বনি দ্বারা উত্পন্ন নতুন লাইনটি দমন করতে অন্য কয়েকটি উত্তরের ব্যবহারটি লক্ষ্য করুন , যা আপনার দ্বিতীয় কমান্ডটি যদি কেবলমাত্র এক লাইন আউটপুট তৈরি করে এবং আপনি তাদের পড়তে সহজ হতে চান তবে তা কার্যকর।
উইলিয়াম তুরেল

দুর্দান্ত সমাধান। একটি যাদুমন্ত্র মত কাজ করে.
ফিলিপ ডেল্টিল

98
find . -type d -exec sh -c "echo -n {}; echo -n ' x '; echo {}" \;

3
আপনি ব্যাশ চালাতে চান তাহলে পরিবর্তে বোর্ন এর আপনার কাছে ব্যবহার করতে পারেন ... -exec bash -c ...পরিবর্তে ... -exec sh -c ...
কেনি এভিট 21

9
{}শেল কোড কখনও এম্বেড করবেন না। দেখুন unix.stackexchange.com/questions/156008/…
কুসালানন্দ

3
+1 @ কুসালানন্দ ফাইলের ইনজেকশন করা ভঙ্গুর এবং নিরাপত্তাহীন। পরামিতি ব্যবহার করুন। দেখতে SC2156
pambda

52

নিম্নলিখিত এক:

find *.txt -exec awk 'END {print $0 "," FILENAME}' {} \;

find *.txt -exec sh -c 'echo "$(tail -n 1 "$1"),$1"' _ {} \;

find *.txt -exec sh -c 'echo "$(sed -n "\$p" "$1"),$1"' _ {} \;

12
{Before এর আগে আন্ডারস্কোরটি কী?
কিড

2
@ কেয়েদ: এটি একটি নিক্ষেপযোগ্য মান যা এর স্থান ধারণ করে $0। "_" find /usr/bin -name find -exec sh -c 'echo "[$0] [$1]"' foobar {} \;: "আউটপুট: " এর পরিবর্তে "ফুবার" দিয়ে এটি ব্যবহার করে দেখুন: "[foobar] [/ usr / bin / find]"।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

1
@ শুওয়াং: হ্যাঁ, আমি বলব যে এটিই কেস। যেমন আপনি জানেন, $0সাধারণত প্রোগ্রামটির নাম ( ARGV[0])।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

3
এই পদ্ধতির জন্য এটি সমালোচনাযোগ্য যে স্ক্রিপ্টটি পাস sh -cহয়েছে একক উদ্ধৃতিতে, দ্বিগুণ নয়। অন্যথায় $1ভুল সুযোগ হয়।
নিক

1
@ নিকের উদ্ধৃতিগুলির সাথে কোনও সম্পর্ক নেই - আপনি '$1'যতক্ষণ পরিবর্তনশীল ( "\$1") এড়িয়ে চলবেন ততক্ষণ আপনি ডাবল উদ্ধৃতি দিয়ে লিখতে পারেন । আপনি অন্য অক্ষরগুলিও এড়িয়ে যেতে পারেন ( "\"")।
ক্যামিলো মার্টিন

22

আর একটি উপায় এটির মতো:

multiple_cmd() { 
    tail -n1 $1; 
    ls $1 
}; 
export -f multiple_cmd; 
find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;

এক লাইনে

multiple_cmd() { tail -1 $1; ls $1 }; export -f multiple_cmd; find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;
  • "multiple_cmd() " - একটি ফাংশন
  • "export -f multiple_cmd " - এটিকে রফতানি করবে যাতে অন্য কোনও সাবস্কেল এটি দেখতে পারে
  • " find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;" - এটি আপনার উদাহরণে ফাংশনটি কার্যকর করবে এটি সন্ধান করুন

এইভাবে একাধিক_সিমিডি আপনার প্রয়োজন হিসাবে দীর্ঘ এবং জটিল হতে পারে।

আশাকরি এটা সাহায্য করবে.


নিখুঁত, ঠিক আমার যা দরকার!
অ্যানেন্ট্রপিক

ওএসএক্স
টমাস

@ থমাস এটি করে তবে ওএসএক্সে পরীক্ষিত এই একটি লাইনার ব্যবহার করে দেখুন। আমি সেখানে কিছু ফাইল / ডায়ার দিয়ে 'আ' নামে একটি ডিরেক্টরি তৈরি করেছি এবং এটিতে সিডিডি করেছি। তারপরে, ~/aaa$ acmd() { echo x \"$1\" x; }; export -f acmd; find . -exec bash -c 'acmd {}' \;
বার্লপ

@ বার্লপ, আমি চেষ্টা করে দেখব; ধন্যবাদ!
টমাস

14

একটি সহজ উপায় আছে:

find ... | while read -r file; do
    echo "look at my $file, my $file is amazing";
done

বিকল্পভাবে:

while read -r file; do
    echo "look at my $file, my $file is amazing";
done <<< "$(find ...)"

1
ফাইলের নামগুলিতে সেগুলিতে নতুন লাইন থাকতে পারে, এই কারণেই এটি অনুসন্ধান--প্রিন্ট 0 টি যুক্তি এবং xargs এর -0 টি যুক্তি রয়েছে
অ্যাবাস্টারফিল্ড

@ আবাস্টারফিল্ড আমি সর্বদা আশা করি বন্য লোকের মধ্যে কখনও তাদের খুঁজে না পাব
কামিলো মার্টিন

1
আমি যা করতে চেয়েছিলাম তা ছিল "সন্ধান করুন ... -Exec zcat {} | wc -l \;" যা কাজ করেনি তবে, সন্ধান করুন ... | পড়ার সময় ফাইল; "$ ফাইল: zcat $file | wc -l" প্রতিধ্বনি করুন ; কাজ কাজ করে, তাই আপনাকে ধন্যবাদ!
গ্রেগ ডগের্টি

উপরের মন্তব্যে আমার কাছে "zcat $ file | wc -l" এর আশেপাশে "ব্যাক টিক্স" রয়েছে। দুর্ভাগ্যক্রমে এইগুলি এগুলিকে ফর্ম্যাটিংয়ে পরিণত করে, তাই আমি এটিকে সঠিক কোডটি দৃশ্যমান সহ একটি আসল উত্তর হিসাবে যুক্ত করেছি
গ্রেগ ডগের্টি

1
@ গ্রেগডুঘের্টি আপনি `যেমন ব্যাকস্ল্যাশ ব্যবহার করেন তা করতে আপনি ব্যাকটিক্স থেকে বাঁচতে পারেন: \​`(তবুও, এটি $()পরিবর্তে ব্যবহারের আরও একটি ভাল কারণ )।
ক্যামিলো মার্টিন

8

আপনি যদি এটি সন্ধানের মাধ্যমে এটি করতে পারেন তবে আমি জানি না, তবে একটি বিকল্প সমাধান হ'ল শেল স্ক্রিপ্ট তৈরি করা এবং এটি অনুসন্ধানের সাথে চালানো।

lastline.sh:

echo $(tail -1 $1),$1

স্ক্রিপ্টটি কার্যকর করা যায় Make

chmod +x lastline.sh

ব্যবহার find:

find . -name "*.txt" -exec ./lastline.sh {} \;

7
ব্যাকটিকগুলি অবহেলা করা হয়েছে, দয়া করে $ (...) এর ব্যবহারটি উত্সাহিত করুন যা আরও ভাল পাঠযোগ্য, স্বতন্ত্রভাবে নির্ভরযোগ্য এবং নীড়ের কাছে সহজ। ধন্যবাদ.
ব্যবহারকারী অজানা

4

ডেনিসের 1 ম উত্তরটি সমস্যার সমাধানের উত্তর। কিন্তু বাস্তবে এটি শিরোনামের পরামর্শ মতো কেবল একটি এক্সিকিউটিভের বেশ কয়েকটি কমান্ডের সাথে সন্ধান করা যায় না। বেশিরভাগ কমান্ডের জিনিসটির সাথে একজনের এক্সিকিউটের উত্তর দিতে আমাদের সমাধান করতে অন্য কোনও কিছুর সন্ধান করতে হবে। এখানে একটি উদাহরণ:

বিভিন্ন {ferences রেফারেন্স ব্যবহার করে 1 এক্সিকিউট কমান্ড ব্যবহার করে গত 7 দিনে পরিবর্তন করা হয়েছে এমন .log ফাইলের সর্বশেষ 10000 লাইন রাখুন

1) দেখুন আদেশগুলি কোন ফাইলগুলিতে কি করবে:

find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "echo tail -10000 {} \> fictmp; echo cat fictmp \> {} " \;

2) এটি করুন: (আর "note>" নোট করুন তবে কেবল ">" এটি চাওয়া হয়েছে)

find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "tail -10000 {} > fictmp; cat fictmp > {} ; rm fictmp" \;


তবে এটি ভেঙে যাবে যদি কোনও ফাইলের নামের একটিতে জায়গা থাকে, আমি বিশ্বাস করি।
কামিলো মার্টিন

4

ক্যামিলো মার্টিনকে ধন্যবাদ, আমি একটি সম্পর্কিত প্রশ্নের উত্তর দিতে সক্ষম হয়েছি:

আমি যা করতে চেয়েছিলাম তা ছিল

find ... -exec zcat {} | wc -l \;

যা কাজ করেনি যাহোক,

find ... | while read -r file; do echo "$file: `zcat $file | wc -l`"; done

কাজ করে, তাই আপনাকে ধন্যবাদ!


2

@ টিঙ্কারের উত্তর প্রসারিত করা,

আমার ক্ষেত্রে, একটি নির্দিষ্ট পাঠ্যযুক্ত ফাইলগুলিতে ফাইলের নাম এবং পাওয়া টেক্সট উভয়ই মুদ্রণের জন্য আমাকে একটি command | command | commandঅভ্যন্তর তৈরি করতে হবে -exec

আমি এটি দিয়ে সক্ষম হয়েছি:

find . -name config -type f \( -exec  grep "bitbucket" {} \; -a -exec echo {} \;  \) 

ফলাফল হলো:

    url = git@bitbucket.org:a/a.git
./a/.git/config
    url = git@bitbucket.org:b/b.git
./b/.git/config
    url = git@bitbucket.org:c/c.git
./c/.git/config

1
আপনি একটি প্যারামিটার দিয়ে কমান্ডের /dev/nullদ্বিতীয় তর্ক হিসাবে পাস করে ফাইলের নাম এবং গ্রেপড সামগ্রী একটি এক লাইনেও মুদ্রণ করতে পারেন :grep-execfind . -name config -type f -exec grep "bitbucket" {} /dev/null \;
বিল ফেইথ

1

xargs ব্যবহার করা উচিত :)

find *.txt -type f -exec tail -1 {} \; | xargs -ICONSTANT echo $(pwd),CONSTANT

অন্য একটি (অসক্সে কাজ করা)

find *.txt -type f -exec echo ,$(PWD) {} + -exec tail -1 {} + | tr ' ' '/'

3
findকমান্ড লাইনের জন্য মেলা ফাইলগুলির সংখ্যা খুব বেশি - এমন পরিস্থিতিতে এটি একটি বড় ব্যবহারের ক্ষেত্রে নজর রাখে । -execএই সীমাটি অতিক্রম করার একটি উপায়। কোনও ইউটিলিটির বাইরে পৌঁছানো সেই সুবিধাটি বাদ দেয়।
ক্রিস জনসন

xargs -nআমন্ত্রণ অনুযায়ী প্রতি ম্যাচের সংখ্যা চয়ন করতে উপস্থিত। প্রতিটি ম্যাচের জন্য xargs -n 1 foocmdকার্যকর করা হবে foocmd {}
অ্যান্ড্রুএফ

0

একটি find+xargsউত্তর।

নীচের উদাহরণটি সমস্ত .htmlফাইল সন্ধান করে এবং .BAKসংযোজনযুক্ত এক্সটেনশন (যেমন 1.html> 1.html.BAK) সহ একটি অনুলিপি তৈরি করে ।

একাধিক স্থানধারক সহ একক কমান্ড

find . -iname "*.html" -print0 | xargs -0 -I {} cp -- "{}" "{}.BAK"

একাধিক স্থানধারক সহ একাধিক কমান্ড

find . -iname "*.html" -print0 | xargs -0 -I {} echo "cp -- {} {}.BAK ; echo {} >> /tmp/log.txt" | sh

# if you need to do anything bash-specific then pipe to bash instead of sh

এই কমান্ডটি এমন ফাইলগুলির সাথেও কাজ করবে যা হাইফেন দিয়ে শুরু হয় বা স্পেস যেমন -my file.html প্যারামিটারের উদ্ধৃতিতে ধন্যবাদ এবং এর --পরে প্যারামিটারগুলির শেষ এবং প্রকৃত ফাইলের নামের শুরুতে cpসংকেত দেয় cp

-print0 নাল-বাইট টার্মিনেটরগুলির সাথে ফলাফলগুলি পাইপ করে।


জন্য xargs-I {} পরামিতি সংজ্ঞায়িত করে {}স্থানধারক হিসেবে; আপনি যে কোনও স্থানধারক পছন্দ করেন তা ব্যবহার করতে পারেন; -0ইঙ্গিত দেয় যে ইনপুট আইটেমগুলি নাল-বিচ্ছিন্ন।

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