সন্ধান + xargs: আর্গুমেন্ট লাইনটি খুব দীর্ঘ


21

আমার নীচের মত একটি লাইন আছে:

find /foo/bar -name '*.mp4' -print0 | xargs -i {} -0 mv -t /some/path {}

তবে আমি নিম্নলিখিত ত্রুটি পেয়েছি:

xargs: argument line too long

আমি দ্বিধান্বিত. xargsএই সমস্যাটির সাথে সঠিকভাবে সাহায্য করার কথা বলে কি না ?

দ্রষ্টব্য: আমি জানি যে আমি প্রযুক্তিগতভাবে সন্ধানে ব্যবহার করতে পারি -exec, তবে আমি বুঝতে চাই যে উপরেরটি কেন ব্যর্থ হয়, কারণ আমার বোধগম্যতাটি xargsকীভাবে ইনপুটটিকে পরিচালনাযোগ্য আকারে এটি আর্গুমেন্টের মধ্যে বিভক্ত করতে পারে তা জানার কথা বলে মনে হয় it এটা কি সত্য নয়?

এই সব zsh ​​সঙ্গে।

উত্তর:


11

ভাল একটি জিনিসের জন্য -iস্যুইচ হ্রাস করা হয়েছে:

-i[replace-str]
     This  option  is a synonym for -Ireplace-str if replace-str is specified. 
     If the replace-str argument is missing, the effect is the same as -I{}. 
     This option is deprecated; use -I instead.

সুতরাং আমি যখন আপনার আদেশটি এটির কাছে পরিবর্তন করেছি তখন এটি কার্যকর হয়েছিল:

$ find /foo/bar -name '*.mp4' -print0 | xargs -I{} -0 mv -t /some/path {}

উদাহরণ

$ find . -print0 | xargs -I{} -0 echo {}
.
./.sshmenu
./The GIT version control system.html
./.vim_SO
./.vim_SO/README.txt
./.vim_SO/.git
./.vim_SO/.git/objects
./.vim_SO/.git/objects/pack
./.vim_SO/.git/objects/pack/pack-42dbf7fe4a9b431a51da817ebf58cf69f5b7117b.idx
./.vim_SO/.git/objects/pack/pack-42dbf7fe4a9b431a51da817ebf58cf69f5b7117b.pack
./.vim_SO/.git/objects/info
./.vim_SO/.git/refs
./.vim_SO/.git/refs/tags
...

ব্যাবহার -I{}

এই কমান্ডটি নির্মাণের পরে এই পদ্ধতির ব্যবহার করা উচিত নয়:

$ find -print0 ... | xargs -I{} -0 ...

পরোক্ষভাবে এইসব সুইচ সক্রিয় xargs, -xএবং -L 1-L 1কনফিগার করে xargsযাতে এটি কমান্ড ডাকছে আপনি এটি একটি একক ফ্যাশন মাধ্যমে ফাইল চালাতে চান।

সুতরাং এটি xargsএখানে ব্যবহারের উদ্দেশ্যকে পরাভূত করে যেহেতু আপনি যদি এটি 1000 ফাইল দেন এটি mv1000 বার কমান্ডটি চালাচ্ছে ।

তাহলে আমার কোন পদ্ধতিটি ব্যবহার করা উচিত?

আপনি এটির মতো xargs ব্যবহার করে এটি করতে পারেন:

$ find /foot/bar/ -name '*.mp4' -print0 | xargs -0 mv -t /some/path

বা সবে এটি সন্ধান করুন:

$ find /foot/bar/ -name '*.mp4' -exec mv -t /some/path {} +

ধন্যবাদ! আপনি যখন বলেছিলেন "This approach shouldn't be used"যে এর পরিবর্তে কোন পদ্ধতিটি ব্যবহার করা উচিত? চান "find /foot/bar/ -name '*.csv' -print0 | xargs -0 mv -t some_dir'"ভাল সমাধান হতে পারে? যদি তাই হয়, কিভাবে নেই xargsযেখানে এই ক্ষেত্রে জানেন mvআর্গুমেন্ট এটা নল থেকে পায় ফিড কমান্ড? (এটি কি সর্বদা তাদের সর্বশেষে রাখে?)
আমেলিও ভাস্কেজ-রেইনা

@ ব্যবহারকারী 815423426 - কেবলমাত্র দিয়ে find ... -exec ...এটি করা একটি ভাল উপায় বা আপনি যদি xargsএটি ব্যবহার করতে চান তবে find ... | xargs ... mv -t ...এটিও ঠিক আছে। হ্যাঁ এটি সর্বদা তাদের শেষ রাখে। সে কারণেই এই পদ্ধতির প্রয়োজন -t
slm

5

বিকল্পটি -iএকটি alচ্ছিক যুক্তি গ্রহণ করে। যেহেতু আপনি পরে একটি স্থান রেখেছেন -i, -iবিকল্পটির পক্ষে কোনও যুক্তি ছিল না এবং ফলস্বরূপ পরবর্তীটি 6 অপারেশনগুলির দ্বিতীয়টি নয় তবে -0বিকল্প ছিল ।xargs{} -0 mv -t /some/path {}

কেবলমাত্র বিকল্প সহ -i, xargs ফাইলের নামের একটি নতুন লাইন-বিচ্ছিন্ন তালিকা প্রত্যাশা করেছিল। ইনপুটটিতে সম্ভবত কোনও নতুন লাইন ছিল না, তাই xargs একটি বিশাল ফাইলের নামের মতো দেখতে পেয়েছিল (এম্বেডড নাল বাইট সহ, তবে xargs এটি চেক করে নি)। পুরো আউটপুট সমন্বিত এই একক স্ট্রিংটি findসর্বাধিক কমান্ড লাইন দৈর্ঘ্যের চেয়ে দীর্ঘ ছিল, সুতরাং ত্রুটিটি "কমান্ড লাইনটি দীর্ঘ"।

আপনার আদেশ -i{}পরিবর্তে এর সাথে কাজ করতে হবে -i {}। বিকল্পভাবে, আপনি ব্যবহার করতে পারেন -I {}: -Iঅনুরূপ -i, তবে একটি বাধ্যতামূলক আর্গুমেন্ট গ্রহণ করে, সুতরাং পরবর্তী আর্গুমেন্টটি বিকল্পের xargsআর্গুমেন্ট হিসাবে ব্যবহৃত হয় -I। তারপরে আর্গুমেন্টটি -0যা বিকল্প হিসাবে ব্যাখ্যা করা হয় ইত্যাদি।

তবে আপনার মোটেও ব্যবহার -I {}করা উচিত নয় । ব্যবহার -Iতিন প্রভাব আছে:

  • -Iউদ্ধৃতি প্রক্রিয়াকরণ বন্ধ করে দেয়, যা -0ইতিমধ্যে তা করে।
  • -Iস্ট্রিং প্রতিস্থাপনের জন্য পরিবর্তন করে তবে {}এটি ডিফল্ট মান।
  • -Iপ্রতিটি ইনপুট রেকর্ডের জন্য কমান্ডটি পৃথকভাবে কার্যকর করাতে বাধ্য করে, যা এখানে অনর্থক কারণ আপনার কমান্ড ( mv -t) বিশেষভাবে প্রতি অনুরোধের জন্য একাধিক ফাইলের সাথে লড়াই করার উদ্দেশ্যে।

হয় ড্রপ -Iএবং -iপুরোপুরি

find /foo/bar -name '*.mp4' -print0 | xargs -0 mv -t /some/path {}

বা xargs ছেড়ে এবং ব্যবহার -exec:

find /foo/bar -name '*.mp4' -exec mv -t /some/path {} +

0

লুপের জন্য একটি ব্যাশ ব্যবহার করে দেখুন:

for FILE in *.mp4 ; do rm $FILE ; done

বা আপনি যদি দেখতে চান তা কী চলছে:

for FILE in *.mp4 ; do echo Removing $FILE ; rm $FILE ; done

0

আপনি যদি মাছের শেলটি ব্যবহার করার সময় এটি দেখতে পান ।
এটি কীভাবে মাছ প্রতিস্থাপনের স্ট্রিং প্রসারিত করে তা সম্পর্কিত{}

আপনি যদি মাছ ব্যবহার করেন তবে আপনাকে প্রতিস্থাপনের স্ট্রিং থেকে বাঁচতে হবে \{\}

| xargs -I \{\} echo \{\}

বা অন্য একটি প্রতিস্থাপন স্ট্রিং ব্যবহার করুন

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