এক্সগার্স কখন দরকার হয়?


134

xargsকমান্ড সবসময় আমার বিভ্রান্ত। এটির জন্য কি সাধারণ নিয়ম রয়েছে?

নীচের দুটি উদাহরণ বিবেচনা করুন:

$ \ls | grep Cases | less

'কেস' এর সাথে মেলে এমন ফাইলগুলি মুদ্রণ করে, তবে কমান্ডটি পরিবর্তন করতে touchহবে xargs:

$ \ls | grep Cases | touch
touch: missing file operand
Try `touch --help' for more information.

$ \ls | grep Cases | xargs touch

উত্তর:


143

লক্ষ্য প্রোগ্রামটি যে ডেটা গ্রহণ করছে তার মধ্যে পার্থক্য।

আপনি যদি কেবল পাইপ ব্যবহার করেন তবে এটি STDIN (স্ট্যান্ডার্ড ইনপুট স্ট্রিম) -এর ডেটা কাঁচা স্তূপ হিসাবে গ্রহণ করে যা এটি একবারে এক লাইনের মাধ্যমে বাছাই করতে পারে। তবে কিছু প্রোগ্রাম স্ট্যান্ডার্ড ইন তাদের কমান্ডগুলি গ্রহণ করে না, তারা কমান্ডের তর্কগুলিতে এটি বানান প্রত্যাশা করে। উদাহরণ হিসেবে বলা যায় touchতাই মত কমান্ড লাইন উপর একটি প্যারামিটার হিসাবে একটি ফাইলের নাম নেয়: touch file1.txt

আপনি যদি একটি প্রোগ্রাম যা ফাইলের নামের আউটপুট থাকে তাহলে বাইরে মান উপর এবং তাদের ব্যবহার করতে চান আর্গুমেন্ট হিসাবে থেকে touch, আপনি ব্যবহার করতে হবে xargsযা stdin স্ট্রিম তথ্য পড়ে এবং কমান্ড স্থান পৃথক আর্গুমেন্ট প্রতিটি লাইন পরিবর্তন করে।

এই দুটি জিনিস সমতুল্য:

# touch file1.txt
# echo file1.txt | xargs touch

xargsএটি কী করছে এবং কেন এটির প্রয়োজন তা সঠিকভাবে না জানলে ব্যবহার করবেন না । এটি প্রায়শই ক্ষেত্রে হয় যে xargsরূপান্তরকে জোর করার জন্য কাজের চেয়ে আরও ভাল উপায় আছে । রূপান্তর প্রক্রিয়া পলায়ন এবং শব্দের সম্প্রসারণ ইত্যাদির মতো সম্ভাব্য সমস্যাগুলিও পরিপূর্ণ is


2
সতর্কতাটি আমার কাছে কিছুটা স্ট্রিং অনুভব করে। কমান্ড লাইনে ( xargsএবং $(...)) স্ট্রিম পাওয়ার জন্য দুটি সাধারণ বিকল্পের মধ্যে xargs কমান্ড প্রতিস্থাপনের চেয়ে অনেক বেশি নিরাপদ। এবং আমি এটির মধ্যে একটি নতুন লাইন সহ কোনও বৈধ ফাইল নাম জুড়ে আসা কখনই স্মরণ করতে পারি না। কমান্ড প্রতিস্থাপনের সাথে পালিয়ে যাওয়া এবং শব্দের সম্প্রসারণের সমস্যাগুলি কী জার্সস নয়?
ক্যামহ

6
@ ক্যাম: তারা দুজনেরই সম্ভাব্য সমস্যা pit শেলটিতে, আপনাকে ফাইলের নামগুলি স্পেস, ট্যাব এবং নতুন লাইনে বিভক্ত হওয়ার বিষয়ে চিন্তা করতে হবে। এক্সার্গসে আপনাকে কেবল নতুন লাইনের বিষয়ে চিন্তা করতে হবে। Xargs, যদি তুমি আউটপুট সঠিকভাবে ফরম্যাট হয়, আপনি NUL চরিত্র শব্দের / ফাইলের নামের বিভক্ত করতে পারেন পরিবর্তে ( xargs -0), যা সাথে দরকারী find -print0
কেন ব্লুম

না xargsস্থান পৃথক args সঙ্গে শেল মাধ্যমে প্রোগ্রাম কল, অথবা এটি আসলে আর্গুমেন্ট তালিকার অভ্যন্তরীণভাবে (যেমন। সাথে ব্যবহারের জন্য গঠন করা নেই execv/ execp)?
বিশদভাবে

1
এটি এটি অভ্যন্তরীণভাবে নির্মাণ করে এবং এক্সিকিউপি ব্যবহার করে, তাই এটি নিরাপদ। এছাড়াও, জিএনইউ xargs (লিনাক্স এবং অন্য কয়েকটি হিসাবে ব্যবহৃত হিসাবে) আপনাকে ডিলিমিটার হিসাবে নিউলাইনটি নির্দিষ্ট করতে দেয় -d \nযদিও বিএসডি xargs (ওএসএক্স এট আল) এই বিকল্পটিকে সমর্থন করে না বলে মনে হয়।
ফ্লফি

72

ইতিমধ্যে সরবরাহ করা উত্তরগুলিকে প্রসারিত করার জন্য, xargsএকটি দুর্দান্ত কাজ করতে পারেন যা আজকের মাল্টিকোর এবং বিতরণকৃত কম্পিউটিং ল্যান্ডস্কেপগুলিতে ক্রমবর্ধমান গুরুত্বপূর্ণ হয়ে উঠছে: এটি সমান্তরাল প্রক্রিয়া কাজের কাজ করতে পারে।

উদাহরণ স্বরূপ:

$ find . -type f -name '*.wav' -print0 |xargs -0 -P 3 -n 1 flac -V8

একবারে তিনটি প্রক্রিয়া ( -P 3) ব্যবহার করে * .wav => * .ফ্ল্যাক এনকোড হবে ।


কি দারুন. আমার এক সপ্তাহ আগে এটি জানা উচিত ছিল যখন আমি 50GiB ডাব্লুএইভি সহ ঠিক একই জিনিসটি করছিলাম (ওজিজি ব্যবহার ব্যতীত)। :)
আলয়েস মাহডাল

অনুসন্ধানের পরামিতিটি কেন ব্যবহার করবেন না?
ইভজেনি

3
@ এভজেনি -execপ্যারামিটার সমান্তরাল-প্রক্রিয়া জব করবে না।
অ্যাম্ফেটামাইচেন

মনে রাখা ভাল যে -0যুক্তিxargs এটিকে NULLচরিত্রটিকে ইনপুট আইটেমের সীমানা হিসাবে বিবেচনা করে। find -print0আউটপুট নাল-সীমাবদ্ধ আইটেম। ফাইলের নামগুলির জন্য এটি দুর্দান্ত অনুশীলন যা স্পেস, কোট বা অন্যান্য বিশেষ অক্ষর থাকতে পারে।
ড্যান ড্যাসক্লেস্কু

24

xargs বিশেষত দরকারী যখন স্ট্যান্ডিনে আপনার ফাইলপথগুলির একটি তালিকা থাকে এবং তাদের সাথে কিছু করতে চান। উদাহরণ স্বরূপ:

$ git ls-files "*.tex" | xargs -n 1 sed -i "s/color/colour/g"

আসুন এই ধাপে ধাপে পরীক্ষা:

$ git ls-files "*.tex"
tex/ch1/intro.tex
tex/ch1/motivation.tex
....

অন্য কথায়, আমাদের ইনপুটটি সেই পথগুলির একটি তালিকা যা আমরা কিছু করতে চাই।

এই পাথগুলির সাথে xargs কী করে তা সন্ধান করার জন্য echoআপনার কমান্ডের আগে একটি দুর্দান্ত কৌশলটি যুক্ত করা যেমন :

$ git ls-files "*.tex" | xargs -n 1 echo sed -i "s/color/colour/g"
sed -i "s/color/colour/g" tex/ch1/intro.tex
sed -i "s/color/colour/g" tex/ch1/motivation.tex
....

-n 1যুক্তি xargs তার নিজস্ব একটি কমান্ড প্রতিটি লাইন চালু করতে হবে। sed -i "s/color/colour/g"কমান্ডের সব ঘটনার প্রতিস্থাপন করবে colorসঙ্গে colourনির্বাচিত ফাইল জন্য।

মনে রাখবেন যে আপনার পথগুলিতে কোনও স্থান না থাকলে এটি কেবলমাত্র কাজ করে। যদি আপনি এটি করেন তবে আপনার -0পতাকাটি পেরিয়ে জার্সগুলিতে ইনপুট হিসাবে নাল টার্মিনেটেড পাথগুলি ব্যবহার করা উচিত । একটি উদাহরণ ব্যবহার হবে:

$ git ls-files -z "*.tex" | xargs -0 -n 1 sed -i "s/color/colour/g"

যা আমরা উপরে বর্ণিত হিসাবে একইভাবে কাজ করে, তবে কোনও একটিতে যদি এর মধ্যে ফাঁকা স্থান থাকে তবে তা কাজ করে।

এই যে কোনো কমান্ড যে যেমন আউটপুট ফাইলের নামের উৎপন্ন সাথে কাজ করে findবা locate। যদি আপনি এটি প্রচুর ফাইল সহ গিট রিপোজিটরিতে ব্যবহার করতে পারেন তবে এর git grep -lপরিবর্তে এটি ব্যবহার করা আরও দক্ষ হতে পারে git ls-files:

$ git grep -l "color" "*.tex" | xargs -n 1 sed -i "s/color/colour/g"

git grep -l "color" "*.tex"কমান্ড "* .tex" শব্দগুচ্ছ "রং" ধারণকারী ফাইলগুলির একটি তালিকা দিতে হবে।


1
সত্য, তবে আপনি যদি এটি শিখে থাকেন তবে আপনার এটিও শিখতে হবে কেন সন্ধানের আউটপুটটি খারাপ অভ্যাসটি বাদ দিচ্ছে?
ওয়াইল্ডকার্ড

6

আপনার প্রথম যুক্তিটি পার্থক্যটি বেশ ভালভাবে তুলে ধরেছে।

\ls | grep Cases | lessআপনাকে lsএবং এর দ্বারা উত্পাদিত ফাইলের নামের তালিকা ব্রাউজ করতে দেয় grep। তারা ফাইলের নাম হতে পারে তা বিবেচ্য নয়, তারা কেবল কিছু পাঠ্য।

\ls | grep Cases | xargs lessকমান্ডের প্রথম অংশে যাদের নাম উত্পাদিত হয়েছে সেগুলি আপনাকে ব্রাউজ করতে দেয়। xargsইনপুট এবং তার কমান্ড লাইন কমান্ড হিসাবে ফাইল নামের একটি তালিকা নেয় এবং ফাইল নামের সাথে কমান্ড রান তার কমান্ড লাইন।

ব্যবহার করার সময় xargs, মনে রাখবেন যে এটি কোনও অদ্ভুত উপায়ে ইনপুট বিন্যাসের প্রত্যাশা করে: হোয়াইট স্পেস-ডিলিমেটেড, সাথে \, 'এবং "উদ্ধৃত করার জন্য ব্যবহৃত হয় (অস্বাভাবিক উপায়ে, কারণ \অভ্যন্তরের উদ্ধৃতিগুলি বিশেষ নয়)। কেবলমাত্র xargsযদি আপনার ফাইলের নামগুলিতে শ্বেত স্পেস না থাকে তবেই ব্যবহার করুন \'"


@ গিলিস: স্পেস ইস্যুটি ঘুরে দেখার বিকল্প xargsরয়েছে -0, --null(এটি সম্ভবত আপনার কাছ থেকে শিখেছি :)), তাই আমি ধরে নিয়েছি যে আপনি কোনও অপশন xargকলকে উল্লেখ করছেন তবে আমি আপনার উদ্ধৃতিগুলির রেফারেন্স দেখে হতবাক হয়েছি। আপনার কি এর সাথে কোনও লিঙ্ক বা উদাহরণ রয়েছে? .. (PS। | xargs lessহ'ল একটি "কৌশল" + 1 .. ধন্যবাদ ..
পিটার.ও

4

আপনার উদাহরণে আপনাকে কোনও ব্যবহার xargsকরার দরকার নেই যেহেতু findআপনি যা করতে চান তা ঠিক এবং সুরক্ষিতভাবে করবে will

ঠিক আপনি কী ব্যবহার করতে চান তা findহ'ল:

find -maxdepth 1 -name '*Cases*' -exec touch {} +

এই উদাহরণে -maxdepth 1কেবল বর্তমান ডিরেক্টরিতে অনুসন্ধানের অর্থ, কোনও উপ-ডিরেক্টরিতে নামবেন না; ডিফল্টরূপে অনুসন্ধানটি সমস্ত উপ-ডিরেক্টরিতে সন্ধান করবে (যা আপনি প্রায়শই চান) যদি না আপনি ম্যাক্সডেপথ দিয়ে সীমাবদ্ধ করেন। {}যে ফাইলটি তার জায়গায় প্রতিস্থাপিত হবে এবং নাম +দুই শেষ অফ কমান্ড মার্কার এক, অন্যান্য সত্তার হয় ;। তাদের মধ্যে পার্থক্য হ'ল ;প্রতিটি ফাইলের একবারে একটি +করে কমান্ড প্রয়োগ করা হয় , এর অর্থ একই সাথে সমস্ত ফাইলের কমান্ডটি কার্যকর করা হয়। তবে নোট করুন, আপনার শেল সম্ভবত ;নিজের ব্যাখ্যা করার চেষ্টা করবে , সুতরাং আপনার এটির সাথে \;বা এটির মাধ্যমে পালাতে হবে ';'। হ্যাঁ, findএর মতো বেশ কয়েকটি ছোট বিরক্তি রয়েছে তবে এর শক্তি এটির চেয়ে বেশি।

উভয় findএবং xargsপ্রথমে শিখতে কৌশল। আপনাকে সেই আদেশ বা অপশনটি xargsব্যবহার করে শিখতে সহায়তা করুন যা আপনাকে এটি চালাতে চায় কি না তা কার্যকর করতে এবং আপনাকে অনুরোধ করতে চলেছে command-p--interactive

একইভাবে findআপনি কমান্ডটি চালাতে চান কিনা তা আপনাকে অনুরোধ করার -okজায়গায় ব্যবহার করতে পারেন -exec

সেখানে বার, যদিও, যখন findসবকিছু আপনি চান করতে সক্ষম এবং হবে না কোথায় xargsআসে। -execকমান্ড শুধুমাত্র এক উদাহরণ হিসেবে বলা যায় গ্রহণ করবে {}প্রকাশমান, তাই আপনি যদি একটি ত্রুটি পেতে হবে find -type f -exec cp {} {}.bak \;তাই আপনি যদি এর পরিবর্তে তাই মত এটা করতে পারে :find -type f -print0 | xargs -0 -l1 -IX cp X X.bak

আপনি সম্পর্কে আরও জানতে পারেন চালান কমান্ড মধ্যে গনুহ Findutils ম্যানুয়াল

এছাড়াও, আমি উল্লেখ করেছি যে findসুরক্ষিতভাবে আপনি যা চান তা করতে পারে কারণ আপনি যখন ফাইলগুলির সাথে কাজ করছেন তখন আপনি ফাঁকা স্থান এবং অন্যান্য অক্ষরের মুখোমুখি হবেন যা xargsযদি আপনি তার পরিবর্তে নাল অক্ষর দ্বারা বন্ধ হওয়া ইনপুট আইটেম তৈরি করে এমন কোনও কিছু -0বা --nullবিকল্প ব্যবহার না করে সমস্যা তৈরি করে unless সাদা জায়গা।



@ স্পেস বা চর যেমন উইলকার্ড ফাইলের নাম যেমন সমস্যাযুক্ত হতে পারে 'বা "সমস্যা হতে পারে, সেখানে findসমস্যা ছাড়াই এই মামলাগুলি পরিচালনা করবে।
অ্যাকুলিচ

হ্যা আমি জানি. লিঙ্কিত প্রশ্নের আমার উত্তর দেখুন । আমার সম্ভবত এই প্রশ্নটি উপরের মন্তব্যে একটি বিবৃতিতে পুনরায় করা উচিত ছিল বা এর সামনে "প্রশ্নটি দেখুন ..." বাক্যাংশটি যুক্ত করা উচিত ছিল। : ডি
ওয়াইল্ডকার্ড

1

xargs(সহ find, sort, du, uniq, perlএবং অন্য কয়েকজন) বলতে "stdin ফাইলগুলির একটি তালিকা, একটি NUL (0x00) বাইট দ্বারা পৃথক হয়েছে" একটি কম্যান্ড-লাইন সুইচ গ্রহণ করে। এটি ফাঁকা স্থান এবং অন্যান্য মজাদার অক্ষরের সাথে ফাইলের নামগুলি পরিচালনা করা সহজ করে তোলে। ফাইলের নামগুলিতে NUL থাকে না।


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