ভেরিয়েবল এক্সপেনশন সহ বাশ স্ক্রিপ্টে সন্ধান করুন ex


14

আমি নীচে বাশ স্ক্রিপ্টে অনুরূপ একটি কমান্ড চালানোর চেষ্টা করছি। এটির সকল সাবফোল্ডারগুলির মধ্যে অনুসন্ধান করা উচিত $sourcedirএবং একটি নির্দিষ্ট ধরণের সমস্ত ফাইলকে এর মূল স্তরে অনুলিপি করা উচিত $targetdir

#!/bin/bash

# These are set as arguments to the script, not hard-coded
sourcedir="/path/to/sourcedir"
targetdir="/path/to/targetdir"

find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2/`basename "$1"`"' "{}" "$targetdir" \;

এটি বেশ কাছাকাছি বলে মনে হচ্ছে, বাদে এটি {}পাস $2করা হয়নি-exec sh -c ...

ফাইল নামগুলিতে বিশেষ অক্ষরের (বিশেষত একক উদ্ধৃতি অক্ষর) সহিষ্ণুতা সহ আমি এটি যথাসম্ভব "সঠিক পথে" কাছাকাছি করতে চাই।

সম্পাদনা: আমি লোককে xargsশৃঙ্খলাবদ্ধ ব্যবহার বা যুক্তি দেওয়ার পরামর্শ দিচ্ছি । আমি এই ধারণার মধ্যে ছিলাম যে এটি কেবলমাত্র সীমিত সংখ্যক যুক্তির জন্য ঠিক। যদি আমার কাছে, উদাহরণস্বরূপ, হাজার হাজার .jpg ফাইল আমি বহু গ্যালারী ডিরেক্টরি থেকে একটি দৈত্য স্লাইডশো ডিরেক্টরিতে অনুলিপি করার চেষ্টা করছি, আর্গুমেন্ট শৃঙ্খলাবদ্ধ সমাধানগুলি এখনও কাজ করবে?

সম্পাদনা 2: আমার সমস্যাটি ছিল আমি কমান্ডটিতে _শ করার জন্য আমার প্রথম বিকল্পটি হারিয়েছিলাম -exec। যে কেউ ফাইন্ড কমান্ডটি কীভাবে কাজ করবেন সে সম্পর্কে আগ্রহী, যুক্ত করুন _এবং সবকিছু ঠিকঠাক হবে:

find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2"' _ "{}" "$targetdir" \;

আমি নীচে একটি উত্তর গ্রহণ করেছি যদিও এটি একই কাজটি সম্পাদন করে তবে আরও দক্ষ এবং মার্জিত।


4
ঠিক এ কারণেই xargsসীমাবদ্ধ নিয়মিত কমান্ডগুলিতে স্বয়ংক্রিয়ভাবে বিপুল পরিমাণ আর্গুমেন্ট পরিচালনা করতে কখনও তৈরি করা হয়েছিল। এছাড়াও বিবেচনা করার জন্য, বেশিরভাগ সর্বাধিক যুক্তি সীমা, স্ট্যান্ডার্ড জিএনইউ ব্যবহারের জন্য ব্যাপকভাবে উন্নত করা হয়েছে। হাজার হাজার ফাইলের জন্য প্রাসঙ্গিক avo সমস্ত প্রক্রিয়া কাঁটাচামচ এড়িয়ে আপনি একটি কর্মক্ষমতা সুবিধাও দেখতে পাবেন।
জেএম বেকার 20

";" এর পরিবর্তে gnu-find এবং + এর সাহায্যে আপনি অনুসন্ধানের সাথে একসাথে একাধিক যুক্তি পরিচালনা করতে পারেন। এবং আপনি জটিল-টি-প্রিন্ট 0 দিয়ে উত্তীর্ণ যুক্তিটি সংরক্ষণ করুন।
ব্যবহারকারী অজানা

@ ব্যবহারকারী-অজানা: আমি আপনার উত্তরের নীচে এটিতে জবাব দিচ্ছি।
জেএম বেকার

@ ব্যবহারকারী অজানা ভাল, আমি এই কোডটি ভালবাসি। এটি কমপক্ষে পুরোপুরি POSIX- সম্মতিযুক্ত এবং মেশিনে কোনও জিএনইউ স্টাফ ছাড়াই কাজ করবে। এমন সময়গুলি যখন আপনার প্রয়োজন হয়, বিশেষত কাজের সার্ভারগুলিতে।
সিনট্যাক্সেরর

উত্তর:


6

আপনি একটি নির্দিষ্ট ধরনের ফাইলের একটি নির্দিষ্ট ডিরেক্টরিতে অনুলিপি করতে চান? এটি সর্বোত্তমভাবে সম্পন্ন হয়েছে xargsএবং আপনার এটিরও দরকার নেই sh। এটি এটি করার একটি আরও উপযুক্ত উপায়, আরও দক্ষতার সাথে চালানো উচিত।

find "$sourcedir" -type f -name "*.type" | xargs cp -t targetdir

আপনার যদি বিশেষ ফাইলের নাম পরিচালনা করতে NULLহয় তবে আপনার পৃথক হিসাবে ব্যবহার করুন

find "$sourcedir" -type f -name "*.type" -print0 | xargs -0 cp -t "$targetdir"

1
2nd ক্ষেত্রে জন্য যোগ করতে ভুলবেন না -print0করতে findএবং -0করতেxargs
SiegeX

আপনার মন্তব্যটি লক্ষ্য করার আগে @ সিজেএক্স, ইতিমধ্যে তা করছিল।
জেএম বেকার 20

এছাড়াও, NULLআপনি যদি ব্যবহার করেন তবে এটি প্রয়োজনীয় নয় '{}', যখন এটি ব্যবহার করবেন না তখন এটি গুরুত্বপূর্ণ। POSIXসম্মতি ব্যতীত অন্যগুলির মধ্যে একটির মধ্যে আসল সুবিধা হ'ল পারফরম্যান্স।
জেএম বেকার 20

6

আপনাকে {}শেলটি দিয়ে একটি আর্গুমেন্ট হিসাবে পাস করতে হবে তারপরে প্রতিটি আরগের উপর দিয়ে লুপ করতে হবে।

find "$sourcedir" -type f -name "*.type" -exec sh -c 'for f; do cp "$f" "$0"; done' "$targetdir" {} +

দ্রষ্টব্য : এটি যেভাবে কাজ করে তা হ'ল শেলের প্রথম আর্গ শেলটির নাম , আমরা নামটি পাস করে এটি $targetdirব্যবহার করতে পারি এবং তারপরে $0সেই টার্গেটডির অ্যাক্সেসের জন্য শেল স্ক্রিপ্টের ভিতরে বিশেষ পরামিতি ব্যবহার করতে পারি।


1
"$targetdir"একক উদ্ধৃতিতে প্রসারিত হয় না।
এনজোটিব

5

আপনি যদি জর্জের চার্চে বিশ্বাস না করেন:

find "$sourcedir" -type f -name "*.mp3" -exec cp -t "$targetdir" {} +

ব্যাখ্যা:

cp -t a b c d 

ক, খ, সি এবং ডি লক্ষ্য dir যাও ক।

-exec cmd {} +

একের পর এক নয়, একসাথে একটি বৃহত্ ফাইলের কমান্ডের অনুরোধ করুন (যা আপনি যদি ";"পরিবর্তে ব্যবহার করেন তবে মানক +)। এ কারণেই লক্ষ্যবস্তুটিকে সামনে টানতে হবে এবং এটি স্পষ্টভাবে লক্ষ্য হিসাবে চিহ্নিত করতে হবে।

এটি জিনু-ফাইন্ডের জন্য কাজ করে এবং এটি অন্যান্য প্রয়োগের জন্য নাও লাগতে পারে। অবশ্যই এটি---ফ্ল্যাশের উপরও নির্ভর করে।

টেকজিলা অবশ্যই এখন পর্যন্ত সঠিক, যেমন shসিপি চালনার প্রয়োজন হয় না।

আপনি যদি ব্যবহার না করেন xargsযা বেশিরভাগ সময়ই অযৌক্তিকভাবে মিশ্রিত হয় তবে findআপনি পতাকা -print0এবং -0পতাকা শেখার হাত থেকে রক্ষা পেয়েছেন ।


1
অবাকভাবে, যে পদ্ধতিটি যে কেউ পছন্দ করতে পারে তা হ'ল কিছুটা বিষয়ভিত্তিক। যা বলেছিল, এখনও ব্যবহারের কারণ রয়েছে xargs। সবচেয়ে বড় উদাহরণ, আপনি যদি ফাইলগুলি না খুঁজে পান? আমি forসর্বদা সাধারণ লুপগুলির জায়গায় xargs ব্যবহার করি , findসুযোগটি খুব ছোট। এছাড়াও, findকেবলমাত্র এটি সমর্থন করে যে +আপনি যদি জিএনইউ ব্যবহার করছেন তবে findএটি পসিক্সে সংজ্ঞায়িত হয়নি। সুতরাং আপনার findএকা পছন্দ করা নির্দ্বিধায় হওয়া উচিত , এটি জার্গার্স যা কিছু করে তা করে না। আপনি যখন জিএনইউ বিবেচনা করেন আপনিও xargsপাবেন -Pযা মাল্টি-কোর করবে। xargsনির্বিশেষে এটি শেখার মূল্য ।
জেএম বেকার

সাবজেক্টিভিটির কথা বলতে গেলে আমার মতামত স্পষ্টতই আলাদা হয়। উদ্দেশ্যমূলকভাবে অন্যদিকে, আপনার উত্তরটিও সঠিক। এটি উপলব্ধ কয়েকটি সেরা সমাধানগুলির মধ্যে একটি।
জেএম বেকার

@ টেকজিলা: আমি সমান্তরাল আহবানকে সমর্থন করতে শুরু করলে এই সাইটটি আবার দেখা হবে বলে মনে করি। :) বেশিরভাগ ক্ষেত্রে অনুলিপি / চলমান ক্ষেত্রে ডিস্কের গতি হ'ল সীমাবদ্ধ ফ্যাক্টর, তবে এসএসডিগুলি চিত্র পরিবর্তন করতে পারে। আপনি ঠিক বলেছেন, এটি সরবরাহ করার জন্য একটি নন-জিএনইউ সমাধান খুব ভাল জিনিস। অন্যথায়, অনুসন্ধান-সমাধানটি উদ্দেশ্যগতভাবে খাটো, সহজ এবং মাত্র দুটি প্রক্রিয়া ব্যবহার করে।
ব্যবহারকারী অজানা

0
read -p "SOURCE: " sourcedir
read -p "TYPE: " type
read -p "TARGET: " targetdir
find -L $sourcedir -iname "*.$type" -exec cp -v {} $targetdir \;

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