কমান্ড আউটপুটের প্রতিটি লাইনে শেল কমান্ড কিভাবে প্রয়োগ করবেন?


192

ধরুন কমান্ড (যেমন ls -1) থেকে আমার কিছু আউটপুট রয়েছে :

a
b
c
d
e
...

আমি ঘুরেফিরে প্রত্যেককে একটি আদেশ (বলুন echo) প্রয়োগ করতে চাই । যেমন

echo a
echo b
echo c
echo d
echo e
...

ব্যাশে এটি করার সহজতম উপায় কী?


3
ls -1এখানে উদাহরণ হতে পারে তবে এটি মনে রাখা গুরুত্বপূর্ণ যে এর আউটপুটটি পার্স করা ভাল নয় ls। দেখুন: mywiki.wooledge.org/ পার্সিংএলস
কোডফোরস্টার

উত্তর:


217

এটি সম্ভবত ব্যবহার করা সবচেয়ে সহজ xargs। তোমার ক্ষেত্রে:

ls -1 | xargs -L1 echo

-Lপতাকা নিশ্চিত করে ইনপুট সঠিকভাবে পড়া হয়। ম্যান পৃষ্ঠা থেকে xargs:

-L number
    Call utility for every number non-empty lines read. 
    A line ending with a space continues to the next non-empty line. [...]


5
@ ডেনিস, দেখতে এমন দেখাচ্ছে না: ls | xargs -L2 echoএবং ls -1 | xargs -L2 echoদুটি ভিন্ন আউটপুট দিন। প্রাক্তন সবাই এক লাইনে রয়েছেন।
অ্যালেক্স বুদোভস্কি


6
xargsশেল ফাংশন বা শেল বিল্ট-ইন কমান্ড নয় কেবল এক্সিকিউটেবল ফাইলই চালাতে পারে। প্রাক্তনটির জন্য সবচেয়ে ভাল সমাধানটি সম্ভবত readলুপযুক্ত।
পাবউক

12
আমি চাই এই উত্তরটি কীসের -L1জন্য একটি ব্যাখ্যা অন্তর্ভুক্ত করে ।
উইক

163

আপনি প্রতিটি লাইনে একটি বেসিক প্রিপেন্ড অপারেশন ব্যবহার করতে পারেন:

ls -1 | while read line ; do echo $line ; done

অথবা আপনি আরও জটিল ক্রিয়াকলাপের জন্য আউটপুটটি পাইপ করতে পারেন:

ls -1 | sed 's/^\(.*\)$/echo \1/'

1
সেড কমান্ডটি কাজ করছে বলে মনে হচ্ছে না: sh: cho: not found a sh: cho: not foundদেখে মনে হচ্ছে এটি eইডোকে একটি সেড কমান্ড বা অন্য কোনও কিছু হিসাবে গ্রহণ করছে।
অ্যালেক্স বুদোভস্কি

whileলুপের জন্য +1 । cmd1 | while read line; do cmd2 $line; done। বা while read line; do cmd2 $line; done < <(cmd1)যা একটি সাবশেল তৈরি করে না। এটি আপনার sedআদেশের সরলীকৃত সংস্করণ :sed 's/.*/echo &/'
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি।

1
@ অ্যালেক্স: একক উদ্ধৃতিতে ডাবল উদ্ধৃতি পরিবর্তন করুন।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

5
উদ্ধৃত "$line"যখন লুপ, এড়ানোর শব্দ বিভাজন করার জন্য।
ইজিজ

3
পালানো অক্ষরগুলির সাথে জগাখিচু read -r lineঠেকাতে ব্যবহার করার চেষ্টা করুন read। উদাহরণস্বরূপ, echo '"a \"nested\" quote"' | while read line; do echo "$line"; doneদেয় "a "nested" quote"যা তার পলায়ন হারিয়েছে। আমরা যদি আমরা প্রত্যাশিত হিসাবে echo '"a \"nested\" quote"' | while read -r line; do echo "$line"; doneপেতে "a \"nested\" quote"। দেখুন wiki.bash-hackers.org/commands/builtin/read
Warbo

9

আপনি লুপের জন্য একটি ব্যবহার করতে পারেন :

* ফাইলের জন্য; করা
   প্রতিধ্বনি "$ ফাইল"
সম্পন্ন

মনে রাখবেন যে প্রশ্নে থাকা কমান্ডটি যদি একাধিক যুক্তি স্বীকার করে, তবে xargs ব্যবহার করা প্রায়শই কার্যকর কারণ এটি কেবল একাধিকবারের পরিবর্তে একবারে প্রশ্নের ইউটিলিটিটি স্প্যান করতে হবে।


1
এটি xargs এর যথাযথ / নিরাপদ ব্যবহারের বিবরণ দেওয়ার মতো। printf '%s\0' * | xargs -0 ...- অন্যথায়, এটি হোয়াইটস্পেস, কোটস ইত্যাদির ফাইল নামগুলির সাথে বেশ নিরাপদ
চার্লস ডাফি

8

এটি করার জন্য আপনি বাস্তবে সেড ব্যবহার করতে পারেন, তবে এটি GNU সেড হয়।

... | sed 's/match/command \0/e'

কিভাবে এটা কাজ করে:

  1. কমান্ড ম্যাচ সঙ্গে বিকল্প ম্যাচ
  2. প্রতিস্থাপনে কমান্ড কার্যকর করুন
  3. কমান্ড আউটপুট সঙ্গে প্রতিস্থাপন লাইন প্রতিস্থাপন।

ফ্যান্টাস্টিক। আমি ই- কমান্ডটি শেষে দিতে ভুলে গেছি , তবে আপনার উত্তরটি দেখে তা করেছি এবং এটি কার্যকর হয়েছে। আমি যখন 1000 এবং 15000 এর মধ্যে এসইডি একটি লাইনের সাথে মেলে তখন এলোমেলো আইডি যুক্ত করার চেষ্টা করছিলাম। cat /logs/lfa/Modified.trace.log.20150904.pw | sed -r 's/^(.*)(\|006\|00032\|)(.*)$/echo "\1\2\3 - ID `shuf -i 999-14999 -n 1`"/e'
sgsi

6
for s in `cmd`; do echo $s; done

যদি সেন্টিমিডির একটি বড় আউটপুট থাকে:

cmd | xargs -L1 echo

7
যদি cmdএর আউটপুটে ফাঁকা স্থান থাকে তবে প্রথমটি ব্যর্থ হবে।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।


2

xargs ব্যাকস্ল্যাশ, উদ্ধৃতি সহ ব্যর্থ। এর মতো কিছু হওয়া দরকার

ls -1 |tr \\n \\0 |xargs -0 -iTHIS echo "THIS is a file."

xargs -0 বিকল্প:

-0, --null
          Input  items are terminated by a null character instead of by whitespace, and the quotes and backslash are
          not special (every character is taken literally).  Disables the end of file string, which is treated  like
          any  other argument.  Useful when input items might contain white space, quote marks, or backslashes.  The
          GNU find -print0 option produces input suitable for this mode.

ls -1আইটেমগুলিকে নিউলাইন চরিত্রগুলি দিয়ে শেষ করে, তাই trএগুলি নাল অক্ষরে অনুবাদ করে।

এই পদ্ধতিটি ম্যানুয়ালি পুনরাবৃত্ত হওয়ার চেয়ে প্রায় 50 গুণ ধীর for ...( মাইকেল অ্যারন সাফিয়ান এর উত্তর দেখুন) (3.55s বনাম 0.0.ss) s তবে অন্যান্য ইনপুট কমান্ডগুলির যেমন সনাক্ত (অনুসন্ধান tr \\n \\0 <file), কোনও ফাইল ( ) বা অনুরূপ থেকে পড়ার জন্য , আপনাকে এটির xargsমতো কাজ করতে হবে ।


1

আমার জন্য আরও ভাল ফলাফল:

ls -1 | xargs -L1 -d "\n" CMD

ভাল, কিন্তু নিখুঁত নয়। find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 commandআউটপুট ls -1অস্পষ্ট যেখানে ক্ষেত্রে পরিচালনা করবে ; আপনি প্রতিটি উপর একটি নেতৃস্থানীয় চান না -printf '%P\0'পরিবর্তে ব্যবহার করুন। -print0./
চার্লস ডাফি

1

উদাহরণস্বরূপ, আমি তালিকায় একাধিক কমান্ড চালানোর জন্য গাওক ব্যবহার করতে চাই

ls -l | gawk '{system("/path/to/cmd.sh "$1)}'

তবে পলায়নযোগ্য অক্ষরগুলির পালানো কিছুটা লোমশ পেতে পারে।

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