পাইপ ইনপুট প্রতি লাইন একবার কমান্ড প্রয়োগ?


161

আমি প্রতি ম্যাচের জন্য একবার জাভা কমান্ড চালাতে চাই ls | grep pattern -। এই ক্ষেত্রে, আমি মনে করি আমি করতে পেরেছিলাম find pattern -exec java MyProg '{}' \;তবে আমি সাধারণ কেস সম্পর্কে আগ্রহী - "স্ট্যান্ডার্ড ইনপুটগুলির প্রতিটি লাইনের জন্য একবার কমান্ড চালান" বলার কী সহজ উপায় আছে? (মাছ বা ব্যাশে।)

উত্তর:


91

এটা কি xargsকরে।

... | xargs command

25
বেশ না। printf "foo bar\nbaz bat" | xargs echo wheeফলন হবে whee foo bar baz bat। হতে পারে বিকল্প -Lবা -nবিকল্পগুলি?
জান্ডার

3
@ জেন্ডার প্রশ্নটি বরং সাধারণ ছিল, তাই আমি সাধারণ সরঞ্জামটি দিয়েছি। সত্য, নির্দিষ্ট পরিস্থিতির উপর নির্ভর করে আপনাকে বিকল্পগুলির সাথে এর আচরণটি সামঞ্জস্য করতে হবে।
কিথ

4
... | tr '। n' '\ 0' | xargs -0
vrdhn

7
যেমন, "নির্দিষ্ট পরিস্থিতি যা প্রশ্নের সঠিক উত্তর দেয়"। :)
ম্যাচটিএম

7
আপনি যদি জার্গার্স দিয়ে এটি করার সঠিক উপায়টি দেখতে চান তবে নীচের আমার উত্তরটি দেখুন।
মাইকেল গোল্ডশটেন

166

গৃহীত উত্তর সঠিক ধারণা আছে, কিন্তু কী পাস হয় সুইচ, যার মানে "একবার নিম্নলিখিত কমান্ড ব্যবহার প্রতি আউটপুট লাইন:"xargs-n1

cat file... | xargs -n1 command

অথবা, একটি একক ইনপুট ফাইলের জন্য আপনি পাইপ catসম্পূর্ণরূপে এড়াতে পারেন এবং কেবল সাথে যেতে পারেন:

<file xargs -n1 command

1
সুদের এছাড়াও পর্যন্ত তেমনটি হয়েছে xargsথেকে না চালানো যদি stdinফাঁকা: --no-run-if-empty -r: স্ট্যান্ডার্ড ইনপুট কোনো nonblanks ধারণ না করে, তাহলে কমান্ড চালাতে না। সাধারণত ইনপুট না থাকলেও কমান্ডটি একবার চালানো হয়। এই বিকল্পটি একটি জিএনইউ এক্সটেনশন।
রোনান জউচেট

4
আপনি কিভাবে ভিতরে লাইন অ্যাক্সেস command?
বিটি

এটি xargs এর সঠিক ব্যবহার। -N1 ব্যতীত, এটি কেবলমাত্র সেই কমান্ডগুলিতে কাজ করে যা পরামিতিগুলির তালিকাকে একাধিক আমন্ত্রণ হিসাবে বিবেচনা করে যা সমস্ত না করে।
মাস্টারেক্সিলো

3
printf "foo বার \ nবাজ ব্যাট" | xargs -n1 ইকো হুই কথা দ্বারা বিভক্ত হয় লাইন দ্বারা নয়
Gismo Ranas

112

বাশ বা অন্য কোনও বোর্ন-স্টাইলের শেল (অ্যাশ, কেশ, জেডএস, ...):

while read -r line; do command "$line"; done

read -rস্ট্যান্ডার্ড ইনপুট থেকে একটি লাইন পড়ে ( ব্যাকস্ল্যাশ ব্যাখ্যা না করে, আপনি readএটি -rচান না)। সুতরাং আপনি নিম্নলিখিত দুটি করতে পারেন:

$ command | while read -r line; do command "$line"; done  

$ while read -r line; do command "$line"; done <file

6
আমি চেষ্টা করার পরে tail -f syslog | grep -e something -e somethingelse| while read line; do echo $line; doneএটি কাজ করে না। এটি whileলুপে পাইপযুক্ত একটি ফাইলের সাথে কাজ করেছে tail -f, কেবলমাত্র সাথে কাজ করেছে , ন্যায়বিচারের সাথে কাজ করেছে grep, তবে দুটি পাইপই নয়। প্রদান বিকল্প এটা কাজ করেছেনgrep--line-buffered

প্রতিটি লাইনে স্টিডিনে প্রেরণ করা দরকার থাকলে এটিও কাজ করে:command | while read -r line; do echo "$line" | command ; done
ডেন

21

আমি কীথের সাথে একমত, xargs হ'ল কাজের সর্বাধিক সাধারণ সরঞ্জাম।

আমি সাধারণত 3 ধাপের পদ্ধতির ব্যবহার করি।

  • আপনার সাথে কাজ করতে পছন্দ করা কিছু না পাওয়া পর্যন্ত বেসিক জিনিসগুলি করুন
  • awk দিয়ে লাইন প্রস্তুত করুন যাতে এটি সঠিক বাক্য গঠন হয়
  • তারপরে xargs এটি সম্পাদন করা যাক, সম্ভবত ব্যাশের সহায়তায়।

ছোট এবং দ্রুত উপায় আছে, তবে এই উপায়গুলি প্রায়শই কার্যকর হয়।

একটি সাধারণ উদাহরণ:

ls | 
grep xls | 
awk '{print "MyJavaProg --arg1 42 --arg2 "$1"\0"}' | 
xargs -0 bash -c

2 টি প্রথম লাইনগুলি কাজ করার জন্য কিছু ফাইল নির্বাচন করে, তারপরে অ্যাডক এক্সিকিউট করার জন্য একটি কমান্ড দিয়ে একটি দুর্দান্ত স্ট্রিং প্রস্তুত করে এবং কিছু যুক্তি এবং $ 1 পাইপ থেকে প্রথম কলাম ইনপুট। এবং পরিশেষে আমি নিশ্চিত করেছি যে xargs এই স্ট্রিংটিকে ব্যাশের কাছে প্রেরণ করে যা এটি কার্যকর করে।

এটি কিছুটা ওভারকিল, তবে এটি খুব নমনীয় হওয়ায় এই রেসিপিটি আমাকে অনেক জায়গায় সহায়তা করেছে।


6
দ্রষ্টব্য, xargs -0নাল বাইটটি রেকর্ড বিভাজক হিসাবে ব্যবহার করে, তাই আপনার অ্যাজক মুদ্রণ printf("MyJavaProg --args \"%s\"\0",$1)
বিবরণীটি

@ লেগন: নাল চরটি মিস করেছেন, উত্তরটি আপডেট করবে
জোহান

@ জোহান কোনও বড় বিষয় নয়, তবে আপনি যদি এটি ব্যবহার করেন তবে আপনি awkএটি প্যাটার্ন ম্যাচটি করতে এবং উদাহরণটি এড়িয়ে যেতে পারেন grep ,ls | awk '/xls/ {print...
এরিক রেনোফ

15

জিএনইউ সমান্তরাল সেই ধরণের কাজের জন্য তৈরি। সহজ ব্যবহারটি হ'ল:

cat stuff | grep pattern | parallel java MyProg

আরও জানতে ইন্ট্রো ভিডিওটি দেখুন: http://www.youtube.com/watch?v=OpaiGYxkSuQ


1
catএখানকার কোনও আসল প্রয়োজন নেই যেহেতু grepসরাসরি ফাইলটি পড়তে পারে
এরিক রেনোফ


1
লিঙ্কটির জন্য ধন্যবাদ, আমি অগত্যা সম্মত হই না যে এটি পড়া সহজ, তবে এটি নির্বিশেষে বিবেচিত হয়েছিল তা জেনে ভাল লাগলাম। আমি কেবলমাত্র সামান্য কুঁচকিয়ে বলব যে লিঙ্কটি এখানে আসলে প্রয়োগ হয় না কারণ বিকল্পটি আসলে নয় < stuff grep patternতবে grep pattern stuffকোনও পুনর্নির্দেশ বা বিড়ালের প্রয়োজন নেই। তবুও এটি বস্তুগতভাবে আপনার যুক্তি পরিবর্তন করে না এবং যদি আপনি মনে করেন যে পাইপ থেকে শুরু হওয়া জিনিসগুলি সর্বদা ব্যবহার করা আরও পরিষ্কার হয় catতবে আপনার পক্ষে শক্তি
এরিক রেনোফ

8

এছাড়াও, while readফিশ শেলের লুপ (আমি ধরে নিলাম যে আপনি ট্যাগ ব্যবহার করেছেন তা বিবেচনা করেই আপনি মাছের শেল চান )।

command | while read line
    command $line
end

কয়েকটি পয়েন্ট নোট করুন।

  • read-rসবচেয়ে সাধারণ ব্যবহারের কেসকে সহজ করার জন্য এটি তর্ক করে না এবং এটি আপনার ব্যাকস্ল্যাশগুলির ব্যাখ্যা দেয় না।
  • আপনার উদ্ধৃতি দেওয়ার দরকার নেই $line, যেমন ব্যাশের মতো, মাছ ফাঁক দিয়ে পৃথক করে না।
  • commandনিজেই একটি সিনট্যাক্স ত্রুটি (স্থানধারক যুক্তিগুলির ব্যবহার যেমন ধরার জন্য)। এটি আসল কমান্ড দিয়ে প্রতিস্থাপন করুন।

এর পরিবর্তে & whileযুক্ত করার দরকার নেই ? dodoneend
aff

@ ফাফ এটি বিশেষত ফিশ শেল সম্পর্কে, যার বিভিন্ন বাক্য গঠন রয়েছে।
কনরাড বোরোস্কি

আহ, তাই যে কি মাছ উপায়।
aff

6

আপনার কমান্ড লাইনে সঠিকভাবে ইনপুট আর্গুমেন্টটি isোকানো হয়েছে বা আপনি যদি এটির বেশ কয়েকবার পুনরাবৃত্তি করতে চান তবে আপনাকে ব্যবহার করা দরকার xargs -I{}

উদাহরণ # 1

another_folderবর্তমান ডিরেক্টরিতে সাবফোল্ডারগুলিকে আয়নাতে একটি ফাঁকা ফোল্ডার কাঠামো তৈরি করুন :

    ls -1d ./*/ | xargs -I{} mkdir another_folder/{}
উদাহরণ # 2

স্টিডিন থেকে আগত ফাইল তালিকার একটি ক্রিয়াকলাপ প্রয়োগ করুন, .htmlএক্ষেত্রে একটি .bakএক্সটেনশান যুক্ত করে প্রতিটি ফাইলের একটি অনুলিপি তৈরি করুন :

    find . -iname "*.html" | xargs -I{} cp {} {}.bak

xargsম্যাকোএস / বিএসডি এর জন্য ম্যান পৃষ্ঠা থেকে :

 -I replstr
         Execute utility for each input line, replacing one or more occurrences of
         replstr in up to replacements (or 5 if no -R flag is specified) arguments
         to utility with the entire line of input.  The resulting arguments, after
         replacement is done, will not be allowed to grow beyond 255 bytes; this is
         implemented by concatenating as much of the argument containing replstr as
         possible, to the constructed arguments to utility, up to 255 bytes.  The
         255 byte limit does not apply to arguments to utility which do not contain
         replstr, and furthermore, no replacement will be done on utility itself.
         Implies -x.

লিনাক্স xargsম্যান পৃষ্ঠা :

   -I replace-str
          Replace  occurrences of replace-str in the initial-
          arguments with names read from standard input.  Al
          so,  unquoted  blanks do not terminate input items;
          instead the separator  is  the  newline  character.
          Implies -x and -L 1.

1

সম্ভাব্য অবাঞ্ছিত ইনপুটগুলির সাথে কাজ করার সময় আমি পুরো কাজটি চালানোর আগে ভিজ্যুয়াল পরিদর্শনের জন্য লাইন দ্বারা 'বানান' দেখেছি (বিশেষত যখন এটি মানুষের মেলবক্সের সাফ করার মতো ধ্বংসাত্মক কিছু)।

আমি যা করি তা হ'ল প্যারামিটারগুলির একটি তালিকা উত্পন্ন করা হয় (অর্থাত্ ব্যবহারকারীর নাম), এটিকে একটি-রেকর্ড-প্রতি-লাইন ফ্যাশনে কোনও ফিডে ফিড করুন:

johndoe  
jamessmith  
janebrown  

তারপরে আমি তালিকাটি খুলি vim, এবং এটি অনুসন্ধানের সাথে জাগ্রত করি এবং এক্সপ্রেশনগুলি প্রতিস্থাপন করি যতক্ষণ না আমি পূর্ণ কমান্ডগুলির একটি তালিকা না পাই যার জন্য মৃত্যুদন্ড কার্যকর করা দরকার, যেমন:

/bin/rm -fr /home/johndoe  
/bin/rm -fr /home/jamessmith 

এইভাবে যদি আপনার রেজেক্স অসম্পূর্ণ হয় তবে আপনি দেখতে পাবেন কোন আদেশে সম্ভাব্য সমস্যা রয়েছে (যেমন। /bin/rm -fr johnnyo connor)। এইভাবে আপনি আপনার রেজেক্সটি পূর্বাবস্থায় ফিরিয়ে নিতে পারেন এবং এর আরও নির্ভরযোগ্য সংস্করণ দিয়ে আবার চেষ্টা করে দেখতে পারেন। নাম ম্যাংলিং এর জন্য কুখ্যাত, কারণ ভ্যান গগ, ও'কনর্স, সেন্ট ক্লেয়ার, স্মিথ-ওয়েসনের মতো সমস্ত প্রান্তের কেস যত্ন নেওয়া শক্ত।

এটি করার set hlsearchজন্য দরকারী vimকারণ এটি সমস্ত ম্যাচ হাইলাইট করবে, সুতরাং এটি যদি এটি মেলে না বা অনিচ্ছাকৃত উপায়ে ম্যাচ না করে তবে আপনি সহজেই স্পট করতে পারেন।

একবার আপনার রেজেক্স নিখুঁত হয়ে যায় এবং এটি যে সমস্ত ক্ষেত্রে আপনি যাচাই / ভাবার জন্য পরীক্ষা করতে পারেন তা ধরে ফেললে আমি সাধারণত এটিকে একটি সেড এক্সপ্রেশনে রূপান্তর করি যাতে এটি অন্য রানের জন্য সম্পূর্ণ স্বয়ংক্রিয়ভাবে তৈরি হয়।

যেসব ক্ষেত্রে ইনপুটটির রেখার সংখ্যা আপনাকে ভিজ্যুয়াল ইন্সপেকশন করতে বাধা দেয়, আমি আদেশটি কার্যকর করার আগে পর্দায় (বা আরও ভাল, এখনও একটি লগ) প্রতিধ্বনিত করার পরামর্শ দিচ্ছি, সুতরাং যদি এটির ত্রুটি থেকে যায় তবে আপনি জানেন ঠিক কোন আদেশটি ঘটেছে এটা ব্যর্থ। তারপরে আপনি নিজের আসল পুনর্নির্দেশগুলিতে ফিরে যেতে পারেন এবং আরও একবার সামঞ্জস্য করতে পারেন।


0

যদি কোনও প্রোগ্রাম পাইপটিকে উপেক্ষা করে তবে ফাইলগুলি আর্গুমেন্ট হিসাবে গ্রহণ করে, তবে আপনি কেবল এটি বিশেষ ফাইলটিতে নির্দেশ করতে পারেন /dev/stdin

আমি জাভাটির সাথে পরিচিত নই, তবে আপনি কীভাবে বাশের জন্য এটি করবেন তা এখানে একটি উদাহরণ:

$ echo $'pwd \n cd / \n pwd' |bash /dev/stdin
/home/rolf
/

\nবাশকে নতুন লাইনে অনুবাদ করার জন্য $ প্রয়োজনীয় । আমি নিশ্চিত না কেন।


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