শেলের একাধিক ফাইলের পাইপ


29

আমার একটি অ্যাপ্লিকেশন রয়েছে যা প্রচুর পরিমাণে ডেটা তৈরি করবে যা আমি ডিস্কে সঞ্চয় করতে চাই না। অ্যাপ্লিকেশনটি বেশিরভাগই ডেটা আউটপুট করে যা আমি ব্যবহার করতে চাই না, তবে দরকারী তথ্যের একটি সেট যা পৃথক ফাইলে বিভক্ত হতে হবে। উদাহরণস্বরূপ, নিম্নলিখিত আউটপুট দেওয়া:

JUNK
JUNK
JUNK
JUNK
A 1
JUNK
B 5
C 1
JUNK

আমি অ্যাপ্লিকেশনটি এভাবে তিনবার চালাতে পারি:

./app | grep A > A.out
./app | grep B > B.out
./app | grep C > C.out

এটি আমার যা চাই তা পাবে তবে এতে খুব বেশি সময় লাগবে। আমি সমস্ত আউটপুটগুলিকে একটি ফাইলে ফেলে দিতে এবং তার মাধ্যমে পার্স করতে চাই না।

উপরে প্রদর্শিত তিনটি অপারেশনকে এমনভাবে সংযুক্ত করার কোনও উপায় আছে যে আমাকে একবার কেবল অ্যাপ্লিকেশনটি চালানো এবং এখনও তিনটি পৃথক আউটপুট ফাইলগুলি পাওয়া দরকার?

উত্তর:


78

আপনি যদি টী বর্ণের নাম

./app | tee >(grep A > A.out) >(grep B > B.out) >(grep C > C.out) > /dev/null

(থেকে এখানে )

( প্রক্রিয়া প্রতিস্থাপন সম্পর্কে )


4
আশ্চর্যজনক, ./app | tee >(grep A > A.out) >(grep B > B.out) | grep C > C.out
এটিকেও এর

7
এই প্রশ্নের উত্তরটি এখন একমাত্র সঠিক, প্রশ্নের মূল শিরোনাম "একাধিক প্রক্রিয়াতে পাইপ" দেওয়া হয়েছে।
acelent

3
+1 টি। এটি সর্বাধিক সাধারণভাবে প্রযোজ্য উত্তর, যেহেতু এটি নির্দিষ্ট ফিল্টারিং কমান্ডের সত্যতার উপর নির্ভর করে না grep
রুখ

1
আমি সম্মত হব যে উত্থাপিত প্রশ্নের সেরা উত্তর এবং এটি চিহ্নিত করা উচিত। সমান্তরাল আরেকটি সমাধান (পোস্ট হিসাবে) তবে উপরোক্ত উদাহরণটি কিছু সময়ের সাথে তুলনা করা আরও কার্যকর। অপশনটি যদি এর পরিবর্তে অত্যন্ত সিপিইউ নিবিড় ক্রিয়াকলাপগুলিতে জড়িত থাকে যেমন একাধিক ফাইল সংক্ষেপণ বা একাধিক এমপি 3 রূপান্তর হয় তবে সন্দেহ নেই যে সমান্তরাল সমাধানটি আরও কার্যকর হিসাবে প্রমাণিত হওয়া উচিত।
অসমল্যাবস

32

তুমি ব্যবহার করতে পার awk

./app | awk '/A/{ print > "A.out"}; /B/{ print > "B.out"}; /C/{ print > "C.out"}'

6
প্রশ্নের শিরোনামটি একাধিক প্রক্রিয়ার পাইপ , এই উত্তরটি একাধিক ফাইলগুলিতে "পাইপিং" (রেজেক্স দ্বারা প্রেরণ) সম্পর্কে । যেহেতু এই উত্তরটি গৃহীত হয়েছিল, তাই সেই অনুসারে প্রশ্নের শিরোনাম পরিবর্তন করা উচিত।
acelent

পছন্দ করেছেন আপনি কি মনে করেন এর চেয়ে ভাল শিরোনাম হবে?
sj755

আমি খুব ছোট একটি সম্পাদনা "শেলের একাধিক ফাইলগুলিতে পাইপ" করার পরামর্শ দিয়েছি, এটি পুনর্বিবেচনা মুলতুবি রয়েছে, এটি পরীক্ষা করে দেখুন। আমি মন্তব্যটি গ্রহণ করা থাকলে তা সরিয়ে নেওয়ার প্রত্যাশা করছিলাম।
acelent

@ পাওলোমাদেইরা - আমি শিরোনাম পরিবর্তন করেছি। আপনার সম্পাদনাটি দেখেনি, তবে আপনি সঠিক, শিরোনামে প্রক্রিয়াগুলির ব্যবহার ভুল ছিল যদি এটি গৃহীত উত্তর হয়।
slm

17

আপনি নিজের শেলের প্যাটার্নের সাথে মেলে এমন দক্ষতাও ব্যবহার করতে পারেন :

./app | while read line; do 
     [[ "$line" =~ A ]] && echo $line >> A.out; 
     [[ "$line" =~ B ]] && echo $line >> B.out; 
     [[ "$line" =~ C ]] && echo $line >> C.out; 
 done

অথবা এমনকি:

./app | while read line; do for foo in A B C; do 
     [[ "$line" =~ "$foo" ]] && echo $line >> "$foo".out; 
  done; done

একটি নিরাপদ উপায় যা শুরু থেকে ব্যাকস্ল্যাশ এবং লাইনগুলি মোকাবেলা করতে পারে -:

./app | while IFS= read -r line; do for foo in A B C; do 
     [[ "$line" =~ "$foo" ]] && printf -- "$line\n" >> "$foo".out; 
  done; done

যেহেতু @ স্টাফেনচাজেলাস মন্তব্যগুলিতে উল্লেখ করেছেন, এটি খুব কার্যকর নয়। সম্ভবত সেরা সমাধানটি হ'ল @ অরলিয়ান ওমস '


যে অনুমান ইনপুট ব্যাকস্ল্যাশ বা ঐ খালি বা ওয়াইল্ডকার্ড অক্ষর, বা লাইন যে দিয়ে শুরু ধারণ করে না -n, -e... এছাড়া এটা প্রতি লাইনে বিভিন্ন সিস্টেম কল (এক মানে যেমন ভয়ঙ্কর অদক্ষ হতে যাচ্ছে read(2)চরিত্র প্রতি, ফাইল খোলা হচ্ছে, লেখা প্রতিটি লাইনের জন্য বন্ধ ...)। সাধারণত, while readশেলগুলিতে পাঠ্য প্রক্রিয়াকরণের জন্য লুপগুলি ব্যবহার করা খারাপ অভ্যাস।
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস আমি আমার উত্তর সম্পাদনা করেছি। এটি -nএখন ব্যাকস্ল্যাশ এবং অন্যান্যগুলির সাথে কাজ করা উচিত । যতদূর আমি উভয় সংস্করণটি ফাঁকা দিয়ে ঠিক কাজ করতে পারি, আমি কি ভুল করছি?
টেরডন

না, প্রথম যুক্তিটি printfহ'ল বিন্যাস। আপনাকে এখানে ভেরিয়েবলগুলি অকেজো রেখে যাওয়ার কোনও কারণ নেই।
স্টাফেন চেজেলাস

যদি ইনপুটটিতে শূন্যস্থান থাকে তবে এটি ব্যাশ (এবং অন্যান্য শেলগুলি একইভাবে ক্রাস্টিংগুলি ব্যবহার করে) এও ভেঙে যাবে।
ক্রিস ডাউন

9

আপনার যদি একাধিক কোর থাকে এবং আপনি প্রক্রিয়াগুলি সমান্তরালে থাকতে চান তবে আপনি এটি করতে পারেন:

parallel -j 3 -- './app | grep A > A.out' './app | grep B > B.out' './app | grep C > C.out'

এটি সমান্তরাল কোরগুলিতে তিনটি প্রক্রিয়া উত্সাহিত করবে। আপনি যদি কনসোল, বা একটি মাস্টার ফাইলের কিছু আউটপুট পেতে চান তবে এটির সাথে মিশ্রণ না করে কিছুটা ক্রমে আউটপুট রাখার সুবিধা রয়েছে।

GNU ইউটিলিটি সমান্তরাল ওলে Tange থেকে থেকে নামে সবচেয়ে Repos থেকে প্রাপ্ত করা যাবে সমান্তরাল বা moreutils । উত্স সাভানাহ.গন.আর.গুর্গ থেকে প্রাপ্ত করা যেতে পারে । এছাড়াও একটি প্রাথমিক নির্দেশিকা ভিডিও এখানে

অভিযোজ্য বস্তু

সমান্তরালের আরও সাম্প্রতিক সংস্করণ ব্যবহার করা (আপনার বিতরণ রেপোতে প্রয়োজনীয় সংস্করণ নয়) আপনি আরও মার্জিত নির্মাণ ব্যবহার করতে পারেন:

./app | parallel -j3 -k --pipe 'grep {1} >> {1}.log' ::: 'A' 'B' 'C'

যা পৃথক কোর বা থ্রেডে একটি। / অ্যাপ্লিকেশন এবং 3 টি সমান্তরাল গ্রেপ প্রক্রিয়া চালানোর ফলাফল অর্জন করে (সমান্তরাল নিজেই নির্ধারিত হিসাবে, -j3টিকে alচ্ছিকও বিবেচনা করে তবে এটি শিক্ষামূলক উদ্দেশ্যে এই উদাহরণে সরবরাহ করা হয়)।

সমান্তরাল এর নতুন সংস্করণটি করে প্রাপ্ত করা যেতে পারে:

wget http://ftpmirror.gnu.org/parallel/parallel-20131022.tar.bz2

তারপরে সাধারন আনপ্যাক, সিডি থেকে সমান্তরাল- {তারিখ},। / কনফিগার করুন && Make, sudo make ইনস্টল করুন। এটি সমান্তরাল, ম্যান পৃষ্ঠা সমান্তরাল এবং ম্যান পৃষ্ঠা সমান্তরাল_আত্তীকরণ ইনস্টল করবে।


7

পার্লের একটি এখানে:

./app | perl -ne 'BEGIN {open(FDA, ">A.out") and 
                         open(FDB, ">B.out") and 
                         open(FDC, ">C.out") or die("Cannot open files: $!\n")} 
                  print FDA $_ if /A/; print FDB $_ if /B/; print FDC $_ if /C/'

1
sed -ne/A/w\ A.out -e/B/w\ B.out -e/C/p <in >C.out

... যদি <inপাঠযোগ্য হয় তবে তিনটি আউটফাইলগুলিকে কিছু লেখার আগেই কেটে যাবে।

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