আমার আর এটি করার চেষ্টা করার মতো হৃদয় নেই তবে কমান্ডলাইন ফাইন্ড সেড এক্সিকিউয়ের উত্তরে আমি এটি লিখেছিলাম । প্রশ্নকর্তা সম্ভবত একটি দুটি বা ডিরেক্টরি বাদ দিয়ে পুরো গাছটিকে কীভাবে সরানো যায় তা জানতে চেয়েছিলেন এবং "ওএলডি" স্ট্রিংযুক্ত সমস্ত ফাইল এবং ডিরেক্টরিগুলির পরিবর্তে "নতুন" থাকতে পারে ।
নীচে কীভাবে বেদনাদায়ক ভার্বোসিটির বর্ণনা দেওয়ার পাশাপাশি এই বিল্ট-ইন ডিবাগিংকে অন্তর্ভুক্ত করার ক্ষেত্রেও এই পদ্ধতিটি অনন্য হতে পারে। এটি মূলত সংকলন ব্যতীত লিখিত হিসাবে কিছুই করতে পারে না এবং অনুরোধকৃত কাজটি সম্পাদন করার জন্য এটি করা উচিত এমন সমস্ত কমান্ড বিশ্বাস করে যে এটি পরিবর্তনশীল সমস্ত কমান্ড সংরক্ষণ করে।
এটি স্পষ্টভাবে যতটা সম্ভব লুপগুলি এড়িয়ে যায় । প্যাটার্নেরsed একাধিক ম্যাচের জন্য পুনরাবৃত্ত অনুসন্ধান ছাড়াও যতদূর আমি জানি অন্য কোনও পুনরাবৃত্তি নেই।
এবং সর্বশেষে, এটি সম্পূর্ণ nullসীমাবদ্ধ - এটি ব্যতীত কোনও ফাইলের নামের কোনও অক্ষরে ট্রিপ করে না null। আমার মনে হয় না তোমার এটা হওয়া উচিত।
যাইহোক, এটি সত্যিই দ্রুত। দেখুন:
% _mvnfind() { mv -n "${1}" "${2}" && cd "${2}"
> read -r SED <<SED
> :;s|${3}\(.*/[^/]*${5}\)|${4}\1|;t;:;s|\(${5}.*\)${3}|\1${4}|;t;s|^[0-9]*[\t]\(mv.*\)${5}|\1|p
> SED
> find . -name "*${3}*" -printf "%d\tmv %P ${5} %P\000" |
> sort -zg | sed -nz ${SED} | read -r ${6}
> echo <<EOF
> Prepared commands saved in variable: ${6}
> To view do: printf ${6} | tr "\000" "\n"
> To run do: sh <<EORUN
> $(printf ${6} | tr "\000" "\n")
> EORUN
> EOF
> }
% rm -rf "${UNNECESSARY:=/any/dirs/you/dont/want/moved}"
% time ( _mvnfind ${SRC=./test_tree} ${TGT=./mv_tree} \
> ${OLD=google} ${NEW=replacement_word} ${sed_sep=SsEeDd} \
> ${sh_io:=sh_io} ; printf %b\\000 "${sh_io}" | tr "\000" "\n" \
> | wc - ; echo ${sh_io} | tr "\000" "\n" | tail -n 2 )
<actual process time used:>
0.06s user 0.03s system 106% cpu 0.090 total
<output from wc:>
Lines Words Bytes
115 362 20691 -
<output from tail:>
mv .config/replacement_word-chrome-beta/Default/.../googlestars \
.config/replacement_word-chrome-beta/Default/.../replacement_wordstars
উল্লেখ্য: উপরে functionসম্ভবত প্রয়োজন হবে GNUএর সংস্করণ sedএবং findসঠিকভাবে করার হ্যান্ডেল find printfএবং sed -z -eএবং :;recursive regex test;tকল। এগুলি যদি আপনার কাছে না পাওয়া যায় তবে কার্যকারিতা সম্ভবত কয়েকটি ছোট সামঞ্জস্যের সাথে নকল করা যেতে পারে।
এটি শুরু থেকে যা চেয়েছিলেন তা খুব অল্পবিস্ফোরিত করে শেষ করা উচিত। আমি forkসঙ্গে sed, কিন্তু আমি কিছু অনুশীলন ছিল sedতাই যে আমি কেন এসেছি রিকার্সিভ শাখাবিন্যাস কৌশল। আমার ধারণা, এটি এক ধরনের নাপিত স্কুলে ছাড়ের চুল কাটার মতো। ওয়ার্কফ্লো এখানে:
rm -rf ${UNNECESSARY}
- আমি ইচ্ছাকৃত কোনও ফাংশনাল কল ছাড়লাম যা কোনও প্রকারের ডেটা মুছতে বা নষ্ট করতে পারে। আপনি যে
./appঅযাচিত হতে পারে উল্লেখ । এটি মুছুন বা এটিকে আগেই অন্যত্র সরিয়ে দিন, অথবা, বিকল্প হিসাবে, আপনি এটি প্রোগ্রামিকভাবে \( -path PATTERN -exec rm -rf \{\} \)করার findজন্য একটি রুটিন তৈরি করতে পারেন, তবে এটি আপনার নিজের।
_mvnfind "${@}"
- এর যুক্তিগুলি ঘোষণা করুন এবং কর্মীর ফাংশনটি কল করুন।
${sh_io}এটি বিশেষ করে গুরুত্বপূর্ণ যে এটি ফাংশন থেকে রিটার্ন সংরক্ষণ করে। ${sed_sep}কাছাকাছি দ্বিতীয় আসে; এটি একটি স্বেচ্ছাসেবী স্ট্রিং sedযা ফাংশনটির পুনরাবৃত্তি উল্লেখ করতে ব্যবহৃত হয় । যদি ${sed_sep}এমন কোনও মান সেট করা থাকে যা আপনার যে কোনও পথ- বা ফাইল-নামগুলির মধ্যে সম্ভাব্যভাবে খুঁজে পাওয়া যেতে পারে ... ভাল, কেবল এটি হতে দেবেন না।
mv -n $1 $2
- পুরো গাছটি প্রথম থেকেই সরানো হয়। এটি প্রচুর মাথাব্যথা বাঁচাবে; আমাকে বিশ্বাস কর. আপনি যা করতে চান বাকী - নামকরণ - কেবল ফাইল সিস্টেমের মেটাডেটার বিষয়। উদাহরণস্বরূপ, যদি আপনি এইটিকে একটি ড্রাইভ থেকে অন্য ড্রাইভে বা কোনও প্রকারের ফাইল সিস্টেমের সীমানা জুড়ে নিয়ে যান তবে আপনি একটি কমান্ড দিয়ে একবারে এটি করা ভাল। এটিও নিরাপদ।
-noclobberজন্য বিকল্প সেট নোট করুন mv; লিখিত হিসাবে, এই ফাংশন ${SRC_DIR}যেখানে ${TGT_DIR}ইতিমধ্যে বিদ্যমান উপস্থিত করা হবে না ।
read -R SED <<HEREDOC
- আমি পালানোর ঝামেলা বাঁচানোর জন্য সেডের সমস্ত কমান্ড এখানে অবস্থিত করেছি এবং নীচে সেডগুলিকে খাওয়ানোর জন্য ভেরিয়েবলে পড়তে পারি। নীচে ব্যাখ্যা।
find . -name ${OLD} -printf
- আমরা
findপ্রক্রিয়াটি শুরু করি । সঙ্গে findআমরা শুধুমাত্র কিছু পুনঃনামকরনের প্রয়োজন কারণ ইতিমধ্যে আমরা জায়গা-টু-স্থানের সকল করেনি অনুসন্ধান mvফাংশন প্রথম আদেশের সঙ্গে অপারেশন। উদাহরণস্বরূপ, findএকটি execকলের মতো কোনও সরাসরি পদক্ষেপ গ্রহণের পরিবর্তে আমরা কমান্ড-লাইনটি গতিশীলভাবে তৈরি করতে এটি ব্যবহার করি -printf।
%dir-depth :tab: 'mv '%path-to-${SRC}' '${sed_sep}'%path-again :null delimiter:'
- পরে
findঅবস্থান নির্ণয় করে ফাইল আমরা তা সরাসরি তৈরী করে এবং আউট (কপি করে প্রিন্ট প্রয়োজন সবচেয়ে কমান্ড আমরা আপনার পুনঃনামকরনের প্রক্রিয়া করতে হবে এর)। %dir-depthTacked সম্মুখের প্রতিটি লাইনে শুরুতে নিশ্চিত করার আমরা একটি পিতা বা মাতা বস্তু রয়েছে যা এখনও পুনরায় নাম দেওয়ার সঙ্গে একটি ফাইল বা গাছে ডিরেক্টরির নাম পরিবর্তন করার চেষ্টা করছি না সাহায্য করবে। findআপনার ফাইল সিস্টেম ট্রিটিতে হাঁটতে সমস্ত ধরণের অপ্টিমাইজেশান কৌশল ব্যবহার করে এবং এটি নিরাপদ-ক্রিয়াকলাপের জন্য আমাদের প্রয়োজনীয় ডেটা ফিরিয়ে দেবে তা নিশ্চিত বিষয় নয়। এই কারণেই আমরা পরবর্তী ...
sort -general-numerical -zero-delimited
- আমরা
findএর ভিত্তিতে সমস্তগুলির আউটপুটটি বাছাই করি %directory-depthযাতে $ {এসআরসি relationship এর সাথে নিকটতম পাথগুলি প্রথমে কাজ করা হয়। এটি mvঅস্তিত্বহীন লোকেশনে ফাইলগুলি যুক্ত সম্ভাব্য ত্রুটিগুলি এড়িয়ে চলে এবং এটি পুনরাবৃত্ত লুপিংয়ের জন্য প্রয়োজনীয়তা হ্রাস করে। ( প্রকৃতপক্ষে, আপনি কোনও লুপ খুঁজে পেতে খুব চাপে থাকতে পারেন )
sed -ex :rcrs;srch|(save${sep}*til)${OLD}|\saved${SUBSTNEW}|;til ${OLD=0}
- আমি মনে করি এটি সম্পূর্ণ স্ক্রিপ্টের একমাত্র লুপ, এবং এটি
%Pathপ্রতিটি স্ট্রিংয়ের জন্য দ্বিতীয় মুদ্রণের উপরে লুপ করে যদি এটির ক্ষেত্রে একাধিক {{ওল্ড} মান থাকে যা পরিবর্তনের প্রয়োজন হতে পারে} অন্যান্য সমস্ত সমাধান যা আমি কল্পনা করেছিলাম একটি দ্বিতীয় sedপ্রক্রিয়া জড়িত , এবং একটি সংক্ষিপ্ত লুপটি কাম্য নাও হতে পারে, অবশ্যই এটি বিস্তৃত হয় এবং একটি সম্পূর্ণ প্রক্রিয়া কাঁটাচামচ করে।
- সুতরাং মূলত
sedএখানে যা করা আছে তা হ'ল} {সেড_সেসপ for অনুসন্ধান করা, তারপরে এটি খুঁজে পেয়ে এটি সংরক্ষণ করে এবং সমস্ত অক্ষর এটির মুখোমুখি হয় যতক্ষণ না এটি $ {পুরানো finds সন্ধান করে, যা এরপরে এটি $ {NEW with দিয়ে প্রতিস্থাপন করে} এরপরে এটি $ $ sed_sep to এ ফিরে যায় এবং আবার স্ট্রিংয়ের ক্ষেত্রে এটি একাধিকবার ঘটে case {OLD for এর জন্য আবার সন্ধান করে। যদি এটি না পাওয়া যায় তবে এটি পরিবর্তিত স্ট্রিংটি মুদ্রণ করে stdout(এটি এটি পরে আবার ধরা পড়ে) এবং লুপটি শেষ করে।
- এটি পুরো স্ট্রিংটিকে বিশ্লেষণ করা এড়ানো যায় এবং নিশ্চিত করে যে
mvকমান্ড স্ট্রিংয়ের প্রথমার্ধে অবশ্যই $ {ওল্ড include অন্তর্ভুক্ত করা দরকার, এটি অন্তর্ভুক্ত করে এবং দ্বিতীয় অর্ধেকটি মুছে ফেলার জন্য যতবার পরিবর্তন করা হয় Destination {ওল্ড} mvএর গন্তব্য পথের নাম ।
sed -ex...-ex search|%dir_depth(save*)${sed_sep}|(only_saved)|out
- এখানে দুটি
-execকল একটি সেকেন্ড ছাড়াই ঘটে fork। প্রথম, আমরা দেখা করেছি, আমরা পরিবর্তন mvকমান্ড হিসাবে দ্বারা সরবরাহকৃত findএর -printfপ্রয়োজনীয় হিসাবে ফাংশন কমান্ড সঠিকভাবে $ {নতুন} এ $ {পুরোনো} এর সমস্ত রেফারেন্স পরিবর্তন করতে, কিন্তু অর্ডার কাজ করার জন্য তাই আমরা কিছু ব্যবহার ছিল যথেচ্ছ রেফারেন্স পয়েন্টগুলি চূড়ান্ত আউটপুটে অন্তর্ভুক্ত করা উচিত নয়। সুতরাং একবারে sedএটি করার দরকার সমস্ত শেষ হয়ে গেলে , আমরা এটিটি পাশ করার আগে হোল্ড-বাফার থেকে এর রেফারেন্স পয়েন্টগুলি মুছে ফেলার নির্দেশ দিই।
এবং এখনই আমরা পিছনে আছি
read এই মত দেখাচ্ছে এমন একটি আদেশ পাবেন:
% mv /path2/$SRC/$OLD_DIR/$OLD_FILE /same/path_w/$NEW_DIR/$NEW_FILE \000
এটি readএটি ফাংশনের বাইরে ইচ্ছামত যাচাই করা যেতে পারে ${msg}হিসাবে এটি হবে ${sh_io}।
শীতল।
-মাইক