প্রতিটি ইনপুট রেখার জন্য xargs একবার কমান্ডটি কার্যকর করুন


341

আমি কীভাবে xargs প্রদত্ত প্রতিটি ইনপুটটির জন্য কমান্ডটি ঠিক একবার সম্পাদন করতে পারি? এটির ডিফল্ট আচরণটি হ'ল লাইনগুলিকে সঙ্কুচিত করা এবং কমান্ড একবার প্রয়োগ করে প্রতিটি দৃষ্টান্তে একাধিক লাইন প্রবাহিত করা।

Http://en.wikedia.org/wiki/Xargs থেকে :

সন্ধান / পাথ-টাইপ এফ-প্রিন্ট 0 | xargs -0 rm

এই উদাহরণস্বরূপ, ফাইলের নামের দীর্ঘ তালিকা সহ ফিজার্সগুলি জার্গাগুলির সন্ধান করুন। xargs তারপরে এই তালিকাটিকে সাবলিস্টে বিভক্ত করে এবং প্রতিটি সাবলিস্টের জন্য একবার rm কল করে। এটি কার্যকরী সমতুল্য সংস্করণের চেয়ে এটি আরও দক্ষ:

সন্ধান / পাথ-টাইপ এফ-এক্সেক আরএম '{}' \;

আমি জানি যে "এক্সিকিউটিভ" পতাকাটি রয়েছে। আমি কেবলমাত্র অন্য একটি উত্স থেকে একটি উদাহরণস্বরূপ উদাহরণ উদ্ধৃত করছি।


4
আপনি যে উদাহরণ সরবরাহ করেছেন তাতে find /path -type f -deleteআরও কার্যকর হতে হবে :)
tzot

xargs ব্যবহার না করার চেষ্টা করুন ...
নায়েব

6
ওপি, আমি জানি এই প্রশ্নটি অনেক পুরানো, তবে এটি এখনও গুগলে আসে এবং স্বীকৃত উত্তরটি ভুল H নীচে আমার দীর্ঘ উত্তর দেখুন।
টোবিয়া

@ টোবিয়ার উত্তরে আপনার গ্রহণটি পরিবর্তন করার বিষয়টি বিবেচনা করুন যা আরও ভাল। স্বীকৃত উত্তরটি নামগুলিতে ফাঁকা স্থান পরিচালনা করে না এবং xargs কমান্ডে একাধিক যুক্তি অনুমোদন করে না যা xargs এর অন্যতম প্রধান বৈশিষ্ট্য।
ধূসর

উত্তর:


392

আপনার ইনপুটটিতে স্পেস না থাকলে কেবল নিম্নলিখিতটি কাজ করবে:

xargs -L 1
xargs --max-lines=1 # synonym for the -L option

ম্যান পেজ থেকে:

-L max-lines
          Use at most max-lines nonblank input lines per command line.
          Trailing blanks cause an input line to be logically continued  on
          the next input line.  Implies -x.

13
আমার পক্ষে এটি আপনি যেমনটি xargs -n 1দিয়েছেন "আর্গুমেন্টের তালিকা খুব দীর্ঘ" হিসাবে প্রকাশিত হতে পারে।
ওয়ার্নাইট

19
যদি MAX-LINESবাদ দেওয়া হয় তবে এটি ডিফল্ট 1 এ xargs -lথাকে , সুতরাং এটি যথেষ্ট। দেখুন info xargs
থোর

3
@ ওয়ার্নাইট: "-n1" প্রতি ইনপুট লাইনে 1 টি প্রার্থনা দেয় না। সম্ভবত আপনার ইনপুট লাইনটি খুব দীর্ঘ ছিল। ডেমো: echo "foo bar" | xargs -n1 echo। তাই আপনি যদি 'এলএস' এর মতো স্টাফগুলিতে পাইপ করেন তবে এটি স্পেসগুলি ভালভাবে পরিচালনা করবে না।
gatoatigrado

8
এটা ভুল. -L 1মূল প্রশ্নের উত্তর দেয় না এবং -n 1এটি কেবল একটি সম্ভাব্য ব্যাখ্যায় করে। নীচে আমার দীর্ঘ উত্তর দেখুন।
টোবিয়া

2
@ টোবিয়া: এটি মূল প্রশ্নের উত্তর দেয়, যা ইনপুটটির লাইনগুলি সম্পর্কে বিশেষভাবে ছিল। ঠিক সেটাই -L 1করে। আমার কাছে, ওপি স্পষ্টতই ডিফল্ট ছোটাছুটি আচরণ এড়ানোর চেষ্টা করছে বলে মনে হয়েছিল এবং এটি গ্রহণ করার পরে আমি ধরে নিয়েছি যে আমি ঠিক আছি। আপনার উত্তরটি কিছুটা পৃথক ব্যবহারের ক্ষেত্রে সম্বোধন করে যেখানে আপনি চানকি আচরণও চান।
ড্রইমন

207

আমার কাছে মনে হয় এই পৃষ্ঠায় বিদ্যমান সমস্ত উত্তর ভুল হিসাবে চিহ্নিত হয়েছে, সঠিক হিসাবে চিহ্নিত হয়েছে including প্রশ্নটি দ্ব্যর্থহীনভাবে কথিত হয়েছে তা থেকে উদ্ভূত হয়।

সংক্ষিপ্তসার:   আপনি যদি প্রতিটি ইনপুট প্রদত্ত প্রতিটি লাইনের জন্য "একবারে" কমান্ডটি কার্যকর করতে চান , সম্পূর্ণ লাইনটি (নতুন লাইন ছাড়াই) একক আর্গুমেন্ট হিসাবে কমান্ডটিতে পাস করতে চান , তবে এটি করার জন্য এটি ইউনিক্সের সাথে উপযুক্ত উপায় way

... | tr '\n' '\0' | xargs -0 -n1 ...

জিএনইউতে xargsকার্যকর এক্সটেনশন থাকতে পারে বা নাও থাকতে পারে যা আপনাকে দূরে সরিয়ে দেয় trতবে ওএস এক্স এবং অন্যান্য ইউএনআইএক্স সিস্টেমে এগুলি উপলভ্য নয়।

দীর্ঘ ব্যাখ্যার জন্য এখন ...


Xargs ব্যবহার করার সময় দুটি বিষয় বিবেচনায় নিতে হবে:

  1. কীভাবে এটি "যুক্তি" তে ইনপুট বিভক্ত হয়; এবং
  2. একসাথে চাইল্ড কমান্ডটি কতটা তর্ক করতে হবে।

Xargs এর আচরণ পরীক্ষা করতে, আমাদের একটি ইউটিলিটি প্রয়োজন যা এটি দেখায় যে এটি কতবার কার্যকর হয়েছে এবং কত যুক্তিযুক্ত। আমি জানি না যে এটির জন্য কোনও স্ট্যান্ডার্ড ইউটিলিটি আছে কিনা তবে আমরা এটি সহজেই ব্যাশে কোড করতে পারি:

#!/bin/bash
echo -n "-> "; for a in "$@"; do echo -n "\"$a\" "; done; echo

ধরে নিলে আপনি এটি showআপনার বর্তমান ডিরেক্টরি হিসাবে সংরক্ষণ করেন এবং এটি কার্যকর করে দেন, এটি এখানে কীভাবে কাজ করে তা এখানে:

$ ./show one two 'three and four'
-> "one" "two" "three and four" 

এখন, যদি আসল প্রশ্নটি সত্যই উপরের পয়েন্ট ২ সম্পর্কে হয় (যেমনটি আমি মনে করি এটি কয়েকবার পড়ার পরে) এবং এটি এইভাবে পড়তে হবে (সাহসী পরিবর্তনগুলি):

প্রদত্ত ইনপুটটির প্রতিটি যুক্তির জন্য আমি কীভাবে xargs কমান্ডটি কার্যকর করতে পারি ? এর ডিফল্ট আচরণটি হ'ল ইনপুটটিকে আর্গুমেন্টের মধ্যে ফেলে দেওয়া এবং কমান্ডটি যতবার সম্ভব চালানো যায় , প্রতিটি বারে একাধিক যুক্তি দিয়ে যায় ।

তারপরে উত্তরটি হ'ল -n 1

আসুন xargs এর ডিফল্ট আচরণের সাথে তুলনা করা যাক যা হোয়াইটস্পেসের চারপাশে ইনপুটকে আলাদা করে দেয় এবং কমান্ডটিকে যতবার সম্ভব কল করে:

$ echo one two 'three and four' | xargs ./show 
-> "one" "two" "three" "and" "four" 

এবং এর সাথে এর আচরণ -n 1:

$ echo one two 'three and four' | xargs -n 1 ./show 
-> "one" 
-> "two" 
-> "three" 
-> "and" 
-> "four" 

অন্যদিকে, যদি আসল প্রশ্নটি ছিল পয়েন্ট ১ সম্পর্কিত। ইনপুট বিভক্ত হওয়া এবং এটি এইভাবে পড়তে হবে (এখানে আসা অনেক লোক মনে হয় এটি কেস, বা দুটি বিষয়কে বিভ্রান্ত করছে):

আমি কীভাবে xargs প্রদত্ত প্রতিটি লাইন ইনপুটটির জন্য ঠিক একটি যুক্তি দিয়ে কমান্ডটি কার্যকর করতে পারি ? এর ডিফল্ট আচরণ হ'ল হোয়াইটস্পেসের চারপাশের লাইনগুলি ছিন্ন করা

তাহলে উত্তরটি আরও সূক্ষ্ম।

কেউ ভাবেন যে -L 1এটি সাহায্য করতে পারে তবে এটি প্রমাণিত হয়েছে যে এটি যুক্তির বিশ্লেষণকে পরিবর্তন করে না। এটি প্রতিটি ইনপুট লাইনের জন্য একবারে কমান্ডটি কার্যকর করে that ইনপুট লাইনে যতগুলি যুক্তি রয়েছে:

$ echo $'one\ntwo\nthree and four' | xargs -L 1 ./show 
-> "one" 
-> "two" 
-> "three" "and" "four" 

শুধু তা-ই নয়, তবে কোনও লাইন যদি সাদা স্থানের সাথে শেষ হয় তবে এটি পরবর্তীটিতে যুক্ত করা হবে:

$ echo $'one \ntwo\nthree and four' | xargs -L 1 ./show 
-> "one" "two" 
-> "three" "and" "four" 

স্পষ্টতই, -Lxargs আর্গুমেন্টগুলিতে যেভাবে ইনপুট বিভক্ত করে তা পরিবর্তন করার বিষয়ে নয়।

ক্রস-প্ল্যাটফর্ম ফ্যাশনে (জিএনইউ এক্সটেনশনগুলি বাদ দিয়ে) একমাত্র যুক্তিটি হ'ল -0, যা এনআুল বাইটসের চারপাশে ইনপুটটি বিভক্ত করে।

তারপরে, এটি NU- র সাহায্যে নতুন লাইনগুলি অনুবাদ করার বিষয় মাত্র tr:

$ echo $'one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 ./show 
-> "one " "two" "three and four" 

এখন আর্গুমেন্ট পার্সিং পুরোপুরি শুভ্রক্ষেত্র সহ, ঠিক আছে।

অবশেষে, আপনি যদি এই কৌশলটির সাথে একত্রিত হন তবে আপনি -n 1প্রতিটি ইনপুট লাইনে ঠিক একটি কমান্ড কার্যকর করতে পারেন, আপনার যা কিছু ইনপুট রয়েছে, এটি মূল প্রশ্নটি দেখার আরও একটি উপায় হতে পারে (সম্ভবত সবচেয়ে স্বজ্ঞাত, শিরোনামটি দেওয়া):

$ echo $'one \ntwo\nthree and four' | tr '\n' '\0' | xargs -0 -n1 ./show 
-> "one " 
-> "two" 
-> "three and four" 

দেখে মনে হচ্ছে এটি আরও ভাল উত্তর। তবে আমি এখনও পুরোপুরি বুঝতে পারি না যে -L এবং -n এর মধ্যে পার্থক্য কী ... আপনি কি আরও কিছু ব্যাখ্যা করতে পারেন?
ওলালা

5
@olala -Lইনপুট লাইনে একবার কমান্ড কার্যকর করে (তবে একটি লাইনের শেষে একটি স্থান এটি পরবর্তী লাইনে যোগ দেয় এবং লাইনটি এখনও সাদা স্থান অনুসারে যুক্তিতে বিভক্ত হয়); -nপ্রতি ইনপুট আর্গুমেন্ট একবার কমান্ড কার্যকর করার সময় । যদি আপনি ->আউটপুট উদাহরণগুলির সংখ্যা গণনা করেন তবে স্ক্রিপ্টটি ./showসম্পাদন করার সময় এটি those
টোবিয়া

আমি দেখি! একটি লাইনের শেষে কোনও স্থান উপলব্ধি করা যায় নি এটি পরের লাইনে যোগ দেয়। ধন্যবাদ!
ওলালা

4
জিএনইউতে xargsদরকারী এক্সটেনশন থাকতে পারে বা নাও থাকতে পারে যা আপনাকে দূরে রাখতে দেয়tr এটির খুব দরকারী এক্সটেনশন রয়েছে; থেকে xargs --help- -d, --delimiter = ইনপুট স্ট্রিমের চরিত্র আইটেমগুলি হোয়াইটস্পেসের সাহায্যে নয়, CHARACTER দ্বারা পৃথক করা হয়; উদ্ধৃতি এবং ব্যাকস্ল্যাশ প্রক্রিয়াজাতকরণ এবং লজিকাল
ইওএফ

এই উত্তরটি সম্পর্কে বিভ্রান্ত বলে মনে হচ্ছে -L-Lপ্রতি লাইনে স্ক্রিপ্টটি কতবার চালিত করতে হবে তা বলে না, এটি বলে যে একসাথে কত লাইন ইনপুট ডেটা গ্রাস করতে হবে।
মোবার্গ

22

আপনি যদি প্রতিটি লাইন (যেমন ফলাফল) থেকে আগত কমান্ডটি চালাতে চান findতবে আপনার কী দরকার xargs?

চেষ্টা করুন:

find আপনার কমান্ড পথ-type f -exec {} \;

আক্ষরিক {}ফাইলের নাম দ্বারা প্রতিস্থাপিত হয় এবং কাস্টম কমান্ডটি এখানে শেষ হয়েছে তা জানতে আক্ষরিক \;প্রয়োজন findহয়।

সম্পাদনা করুন:

(আপনার প্রশ্নের সম্পাদনার পরে আপনি যে সম্পর্কে জানেন তা স্পষ্ট করে -exec)

থেকে man xargs:

-L সর্বোচ্চ-লাইন
সর্বাধিক ব্যবহারের সর্বোচ্চ-লাইন কমান্ড লাইন প্রতি ইনপুট লাইন nonblank। ফাঁকা ফাঁকা স্থানগুলি পরবর্তী ইনপুট লাইনে যৌক্তিকভাবে চালিয়ে যাওয়ার জন্য একটি ইনপুট লাইন তৈরি করে। সূচিত করে -x।

মনে রাখবেন যে ফাঁকা জায়গায় ফাইলের নামগুলি ব্যবহার করা আপনার সমস্যার কারণ হতে পারে xargs:

$ mkdir /tmp/bax; cd /tmp/bax
$ touch a\  b c\  c
$ find . -type f -print | xargs -L1 wc -l
0 ./c
0 ./c
0 total
0 ./b
wc: ./a: No such file or directory

সুতরাং আপনি যদি -execবিকল্পটির বিষয়ে চিন্তা না করেন তবে আপনি আরও ভাল ব্যবহার করুন -print0এবং -0:

$ find . -type f -print0 | xargs -0L1 wc -l
0 ./c
0 ./c
0 ./b
0 ./a

17

আমি কীভাবে xargs প্রদত্ত প্রতিটি ইনপুটটির জন্য কমান্ডটি ঠিক একবার সম্পাদন করতে পারি?

-L 1সরল সমাধান তবে ফাইলগুলির মধ্যে কোনওটিতে ফাঁকা স্থান থাকলে এটি কাজ করে না। এটি -print0আর্গুমেন্টের মূল ফাংশন - হোয়াইটস্পেসের পরিবর্তে 'separate 0' অক্ষর দ্বারা আর্গুমেন্টগুলি আলাদা করা। এখানে একটি উদাহরণ:

echo "file with space.txt" | xargs -L 1 ls
ls: file: No such file or directory
ls: with: No such file or directory
ls: space.txt: No such file or directory

trনিউলাইনগুলিকে নাল ( \0) অক্ষরগুলিতে রূপান্তর করতে এবং তারপরে xargs -0যুক্তিটি ব্যবহার করার একটি আরও ভাল সমাধান । এখানে একটি উদাহরণ:

echo "file with space.txt" | tr '\n' '\0' | xargs -0 ls
file with space.txt

তারপরে যদি আপনার কলগুলির সংখ্যা সীমাবদ্ধ -n 1করতে হয় তবে আপনি প্রতিটি ইনপুটটির জন্য প্রোগ্রামটিতে একটি কল করার জন্য যুক্তিটি ব্যবহার করতে পারেন :

echo "file with space.txt" | tr '\n' '\0' | xargs -0 -n 1 ls

এটি বিরতিগুলি শূন্যে রূপান্তরিত করার আগে আপনাকে অনুসন্ধানের আউটপুট ফিল্টার করতে দেয় ।

find . -name \*.xml | grep -v /target/ | tr '\n' '\0' | xargs -0 tar -cf xml.tar

1
দ্বিতীয় কোড ব্লক ট্র 'সিনট্যাক্স ত্রুটি আছে বোকা হিসাবে প্রতিশ্রুতি দিতে অস্বীকার করছিল কারণ আমার পরিবর্তনটি
htaccess

1
এর অর্থ কী: " -Lএটি ব্যবহারে আরও একটি সমস্যা হ'ল এটি প্রতিটি xargsকমান্ড কলের জন্য একাধিক যুক্তি অনুমোদন করে না ?"
মোবার্গ

আমি এই বহির্মুখী তথ্য @ মোবার্গ সরিয়ে ফেলতে আমার উত্তরকে উন্নত করেছি।
ধূসর


9

এই দুটি উপায়ও কাজ করে এবং অন্যান্য কমান্ডগুলি ব্যবহার করে যা সন্ধান ব্যবহার করে না!

xargs -I '{}' rm '{}'
xargs -i rm '{}'

উদাহরণ ব্যবহারের ক্ষেত্রে:

find . -name "*.pyc" | xargs -i rm '{}'

পাইক ফাইলগুলির ফাঁক থাকলেও এই ডিরেক্টরিতে সমস্ত পিএসি ফাইল মুছে ফেলবে।


এটি প্রতিটি উপাদানগুলির জন্য একটি ইউটিলিটি কল ইস্যু করে যা সর্বোত্তম নয়।
ধূসর

7
find path -type f | xargs -L1 command 

আপনার যা দরকার তা হল।


4

নিম্নলিখিত কমান্ডটি সমস্ত ফাইল (-প্রকার চ) খুঁজে পাবেন /pathএবং তারপরে সেগুলি cpবর্তমান ফোল্ডারে ব্যবহার করে অনুলিপি করবেন । কমান্ড লাইনে -I %কোনও স্থানধারক চরিত্র নির্দিষ্ট করতে হলে ব্যবহারটি নোট করুন cpযাতে ফাইলের নামের পরে যুক্তিগুলি রাখা যায়।

find /path -type f -print0 | xargs -0 -I % cp % .

এক্সার্গস (জিএনইউ আবিষ্কারক) 4.4.0 দিয়ে পরীক্ষিত


2

আপনি যথাক্রমে - ম্যাক্স-লাইন বা - ম্যাক্স-আরগস পতাকা ব্যবহার করে রেখার সংখ্যা বা আর্গুমেন্টের (প্রতিটি যুক্তির মধ্যে ফাঁক থাকলে) সীমাবদ্ধ করতে পারেন।

  -L max-lines
         Use at most max-lines nonblank input lines per command line.  Trailing blanks cause an input line to be logically continued on the next  input
         line.  Implies -x.

  --max-lines[=max-lines], -l[max-lines]
         Synonym  for  the -L option.  Unlike -L, the max-lines argument is optional.  If max-args is not specified, it defaults to one.  The -l option
         is deprecated since the POSIX standard specifies -L instead.

  --max-args=max-args, -n max-args
         Use at most max-args arguments per command line.  Fewer than max-args arguments will be used if the size (see  the  -s  option)  is  exceeded,
         unless the -x option is given, in which case xargs will exit.

0

টোবিয়ার উত্তরের উপরে কোনও মন্তব্য যুক্ত করার মতো যথেষ্ট খ্যাতি আমার কাছে নেই বলে মনে হচ্ছে , তাই xargsউইন্ডোজ প্ল্যাটফর্মগুলিতে আমরা যারা একইভাবে পরীক্ষা করতে চাইছি তাদের সহায়তা করার জন্য আমি এই "উত্তর" যুক্ত করছি ।

এখানে একটি উইন্ডোজ ব্যাচের ফাইল যা টোবিয়ার দ্রুত কোডেড "শো" স্ক্রিপ্টের মতো একই কাজ করে:

@echo off
REM
REM  cool trick of using "set" to echo without new line
REM  (from:  http://www.psteiner.com/2012/05/windows-batch-echo-without-new-line.html)
REM
if "%~1" == "" (
    exit /b
)

<nul set /p=Args:  "%~1"
shift

:start
if not "%~1" == "" (
    <nul set /p=, "%~1"
    shift
    goto start
)
echo.

0

@ ড্রেমন উত্তরগুলি ফাইলের স্থান সহ "-0" দিয়ে সঠিক বলে মনে হচ্ছে।

আমি xargs কমান্ডটি চেষ্টা করছিলাম এবং আমি দেখতে পেলাম যে "-0" "-L" এর সাথে পুরোপুরি কাজ করে। এমনকি স্পেসগুলি চিকিত্সা করা হয় (যদি ইনপুটটি বাতিল হয়ে যায়)। নিচেরটি একটি উদাহরণ :

#touch "file with space"
#touch "file1"
#touch "file2"

নিম্নলিখিতটি নালগুলিকে বিভক্ত করবে এবং তালিকার প্রতিটি যুক্তিতে কমান্ড কার্যকর করবে:

 #find . -name 'file*' -print0 | xargs -0 -L1
./file with space
./file1
./file2

সুতরাং -L1"-0" ব্যবহার করে প্রতিটি নাল টার্মিনেটেড অক্ষরে আর্গুমেন্ট কার্যকর করা হবে। পার্থক্যটি দেখতে চেষ্টা করুন:

 #find . -name 'file*' -print0 | xargs -0 | xargs -L1
 ./file with space ./file1 ./file2

এমনকি এটি একবার কার্যকর করা হবে:

 #find . -name 'file*' -print0  | xargs -0  | xargs -0 -L1
./file with space ./file1 ./file2

"-L" এখন নাল বাইটে বিভক্ত না হওয়ায় কমান্ডটি একবার কার্যকর করা হবে। আপনাকে কাজের জন্য "-0" এবং "-L" উভয়ই সরবরাহ করতে হবে।


-3

আপনার উদাহরণে, xargs এ ফাইন্ডের আউটপুটটি পাইপ করার পয়েন্টটি হ'ল ফাইন্ড-এক্সেক বিকল্পের স্ট্যান্ডার্ড আচরণটি হ'ল প্রতিটি পাওয়া ফাইলের জন্য একবার কমান্ড চালানো ute আপনি যদি সন্ধানটি ব্যবহার করছেন এবং আপনি যদি এর মানক আচরণ চান তবে উত্তরটি সহজ - শুরু করার জন্য xargs ব্যবহার করবেন না।


আসলে, আমি ওপির সম্পাদনাগুলি থেকে যা বোঝাতে পারি তা হ'ল ইনপুট ডেটার কোনও সম্পর্ক নেই findএবং সে কারণেই তারা -execবিকল্পটিকে পছন্দ করে না ।
tzot

-3

বর্তমান বা উপ-ফোল্ডারে প্রতিটি বিল্ড.এক্সএমএল এ পিঁপড়া টাস্ক পরিষ্কার করুন

find . -name 'build.xml' -exec ant -f {} clean-all \;

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