পাইপিং, শিফটিং বা পরামিতি প্রসারণ কি আরও দক্ষ?


26

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

list="1 ant bat 5 cat dingo 6 emu fish 9 gecko hare 15 i j"

সুতরাং আমি কেবল তালিকার মাধ্যমে পুনরাবৃত্তি করতে সক্ষম হতে চাই এবং কেবল 1,5,6,9 এবং 15 অ্যাক্সেস করতে পারি।

সম্পাদনা: আমার স্পষ্ট করে দেওয়া উচিত ছিল যে তালিকা থেকে আমি যে মানগুলি অর্জন করতে চাইছি সেগুলি বাকী তালিকার চেয়ে বিন্যাসে আলাদা হওয়া উচিত নয়। যা তাদের বিশেষ করে তোলে তা কেবল তালিকার তাদের অবস্থান (এই ক্ষেত্রে, অবস্থান 1,4,7 ...)। সুতরাং তালিকা হতে পারে1 2 3 5 9 8 6 90 84 9 3 2 15 75 55তবে আমি এখনও একই সংখ্যা চাই। এবং এছাড়াও, আমি তালিকার দৈর্ঘ্য জানি না ধরে ধরে এটি করতে সক্ষম হতে চাই।

আমি এখন পর্যন্ত যে পদ্ধতিগুলি নিয়ে ভাবলাম সেগুলি হ'ল:

পদ্ধতি 1

set $list
found=false
find=9
count=1
while [ $count -lt $# ]; do
    if [ "${@:count:1}" -eq $find ]; then
    found=true
    break
    fi
    count=`expr $count + 3`
done

পদ্ধতি 2

set list
found=false
find=9
while [ $# ne 0 ]; do
    if [ $1 -eq $find ]; then
    found=true
    break
    fi
    shift 3
done

পদ্ধতি 3 আমি নিশ্চিত যে পাইপিং এটিকে সবচেয়ে খারাপ বিকল্প হিসাবে তৈরি করে, তবে আমি কৌতূহল ছাড়াই এমন একটি পদ্ধতি সন্ধান করার চেষ্টা করছিলাম যা সেট ব্যবহার করে না।

found=false
find=9
count=1
num=`echo $list | cut -d ' ' -f$count`
while [ -n "$num" ]; do
    if [ $num -eq $find ]; then
    found=true
    break
    fi
    count=`expr $count + 3`
    num=`echo $list | cut -d ' ' -f$count`
done

সুতরাং সবচেয়ে দক্ষ হতে হবে, বা আমি একটি সহজ পদ্ধতি অনুপস্থিত?


10
দক্ষতা যদি গুরুত্বপূর্ণ উদ্বেগ হয় তবে আমি প্রথমে শেল স্ক্রিপ্টটি ব্যবহার করব না। আপনার তালিকাটি কত বড় যে এটি একটি পার্থক্য করে?
বার্মার


2
আপনার সমস্যার প্রকৃত উদাহরণগুলির উপর পরিসংখ্যান না করে আপনি কিছুই জানতে পারবেন না। এর মধ্যে "প্রোগ্রামিং এওজেড" এর সাথে তুলনা করা অন্তর্ভুক্ত রয়েছে etc. ইত্যাদি যদি পরিসংখ্যানগুলি খুব ব্যয়বহুল হয় তবে দক্ষতার সন্ধান করা সম্ভবত এটির পক্ষে উপযুক্ত নয়।
ডেভিড টোনহোফার

2
লেভি, আপনার সংজ্ঞাটির "দক্ষ" উপায়টি কী? আপনি পুনরাবৃত্তি করার একটি দ্রুত উপায় খুঁজে পেতে চান?
সের্গেই কোলোডিয়াজনি

উত্তর:


18

খুব সহজ সঙ্গে awk। এটি আপনাকে যে কোনও দৈর্ঘ্যের ইনপুট দেওয়ার জন্য প্রতিটি চতুর্থ ক্ষেত্রের মান পাবে:

$ awk -F' ' '{for( i=1;i<=NF;i+=3) { printf( "%s%s", $i, OFS ) }; printf( "\n" ) }' <<< $list
1 5 6 9 15

এটি বিল্ট-ইন awkভেরিয়েবলগুলি যেমন NF(রেকর্ডে ক্ষেত্রের সংখ্যা) forউপকারের কাজ করে এবং ক্ষেত্রগুলি বরাবর পুনরাবৃত্তি করার জন্য কিছু সাধারণ লুপিং করে যা আপনাকে চাইবে যেগুলি আগে প্রয়োজন তা জানতে না পেরে কতগুলি হবে।

অথবা, যদি আপনি সত্যিই আপনার উদাহরণে উল্লিখিত নির্দিষ্ট ক্ষেত্রগুলি চান:

$ awk -F' ' '{ print $1, $4, $7, $10, $13 }' <<< $list
1 5 6 9 15

দক্ষতার বিষয়ে প্রশ্ন হিসাবে, সবচেয়ে সহজ রুটটি হ'ল timeএটির বা আপনার অন্যান্য প্রতিটি পদ্ধতির পরীক্ষা করা এবং এটি কতক্ষণ সময় নেয় তা দেখানোর জন্য ব্যবহৃত হয়; straceসিস্টেমগুলি কল কীভাবে প্রবাহিত হয় তা দেখার জন্য আপনি সরঞ্জামগুলিও ব্যবহার করতে পারেন। timeদেখতে দেখতে ব্যবহার :

$ time ./script.sh

real    0m0.025s
user    0m0.004s
sys     0m0.008s

সময়ের ব্যবস্থায় কোনটি সবচেয়ে কার্যকরী তা দেখতে আপনি বিভিন্ন ফলাফলের মধ্যে সেই আউটপুটটি তুলনা করতে পারেন; অন্যান্য সরঞ্জামগুলি অন্যান্য দক্ষতার মেট্রিকগুলির জন্য ব্যবহার করা যেতে পারে।


1
ভাল বক্তব্য, @ মিশেলহোমার; "কোন পদ্ধতিটি সর্বাধিক দক্ষ তা আমি কীভাবে নির্ধারণ করতে পারি" এই প্রশ্নে আমি একটি দিক যুক্ত করেছি ।
ডোপঘোতি

2
echoবনাম সম্পর্কিত <<<" লেভিউউজাইক ", "অভিন্ন" খুব শক্ত শব্দ। আপনি stuff <<< "$list"এটি প্রায় অনুরূপ বলতে পারে printf "%s\n" "$list" | stuff। সংক্রান্ত echoবনাম printfআমি কি তোমাদেরকে এই উত্তর
Jol

5
@ ডোপঘোটি আসলে তা করে। <<<শেষে একটি নতুন লাইন যুক্ত করুন। এটি কীভাবে $()শেষ থেকে একটি নতুন লাইন সরায় তার অনুরূপ । এটি কারণ লাইনগুলি নতুন লাইনের মাধ্যমে শেষ করা হয়। <<<একটি রেখা হিসাবে একটি অভিব্যক্তি ফিড, তাই এটি একটি নতুন লাইন দ্বারা বন্ধ করা আবশ্যক। "$()"লাইনগুলি গ্রহণ করে এবং তাদেরকে একটি আর্গুমেন্ট হিসাবে সরবরাহ করে, সুতরাং এটি টার্মিনেটিং নিউলাইনটি সরিয়ে দিয়ে রূপান্তর করা বোধগম্য।
জোল

3
@ লেভিউজডাইক অ্যাডব্লক অনেকটা প্রশংসিত সরঞ্জাম। এটি আপাতদৃষ্টিতে জটিল সমস্যাগুলির সকল প্রকারের সমাধান সহজ করে তুলবে। বিশেষত আপনি যখন শেডের মতো কোনও কিছুর জন্য জটিল রেজেক্স লেখার চেষ্টা করছেন, আপনি প্রায়শই ঘন্টাটিকে ফাঁকে ফাঁকে ফাঁকে প্রক্রিয়াগতভাবে লিখে সংরক্ষণ করতে পারেন। এটি শিখলে বড় লভ্যাংশ হবে ∕
জো

1
@ লেভিউজডাইক: হ্যাঁ awkস্ট্যান্ড- অলোন বাইনারি যা শুরু করতে হবে। পার্ল বা বিশেষত পাইথনের বিপরীতে, ডাব্লু ইন্টারপ্রেটারটি দ্রুত শুরু হয় (এখনও বেশ কয়েকটি সিস্টেম কল করার সমস্ত সাধারণ গতিশীল লিঙ্কার ওভারহেড, তবে অ্যাডক শুধুমাত্র libc / libm এবং libdl ব্যবহার straceকরে eg উদ্বোধনের সূচনা সিস্টেম-কলগুলি পরীক্ষা করার জন্য ব্যবহার ) । অনেকগুলি শেল (বাশের মতো) বেশ ধীরে ধীরে, তাই একটি ছোট্ট ইশ তালিকার আকারগুলির জন্য শেল বিল্ট-ইনগুলির সাথে তালিকায় টোকেনের উপরে লুপিংয়ের চেয়ে একটি অজস্র প্রক্রিয়াটি দ্রুততর করা সম্ভব। এবং কখনও কখনও আপনি একটি লিখতে পারেন #!/usr/bin/awkস্ক্রিপ্ট পরিবর্তে একটি এর #!/bin/shস্ক্রিপ্ট।
পিটার কর্ডস

35
  • সফ্টওয়্যার অপ্টিমাইজেশনের প্রথম নিয়ম: করবেন না

    আপনি যতক্ষণ না প্রোগ্রামটির গতি একটি সমস্যা হিসাবে অবধি জানেন, ততক্ষণে এটি কত দ্রুত তা নিয়ে ভাবার দরকার নেই। যদি আপনার তালিকাটি দৈর্ঘ্য বা মাত্র ~ 100-1000 আইটেম দীর্ঘ, আপনি সম্ভবত এটি কতক্ষণ সময় নেয় তা খেয়াল করবেন না। পার্থক্য কী হবে তার চেয়ে আপনি অপ্টিমাইজেশন সম্পর্কে চিন্তা করতে আরও সময় ব্যয় করার একটি সুযোগ রয়েছে।

  • দ্বিতীয় নিয়ম: পরিমাপ

    এটি অনুসন্ধানের নিশ্চিত উপায় এবং এটি আপনার সিস্টেমের জন্য উত্তর দেয়। বিশেষত শাঁসের সাহায্যে, অনেকগুলি রয়েছে এবং সেগুলি সমস্ত অভিন্ন নয়। একটি শেলের উত্তর আপনার জন্য প্রয়োগ নাও হতে পারে।

    বৃহত্তর প্রোগ্রামগুলিতে, প্রোফাইলিং এখানেও যায়। ধীরতম অংশটি আপনার মনে হয় এটির মতো নাও হতে পারে।

  • তৃতীয়ত, শেল স্ক্রিপ্ট অপ্টিমাইজেশনের প্রথম নিয়ম: শেলটি ব্যবহার করবেন না

    হাঁ সত্যিই. অনেকগুলি শেল দ্রুত তৈরি হয় না (যেহেতু বাহ্যিক প্রোগ্রামগুলি আরম্ভ করার দরকার হয় না), এবং তারা প্রতিবার সোর্স কোডের লাইনগুলি আবারও পার্স করতে পারে।

    পরিবর্তে awk বা পার্ল জাতীয় কিছু ব্যবহার করুন। একটি তুচ্ছ মাইক্রো-বেঞ্চমার্কে আমি করেছি, awkএকটি সাধারণ লুপ চালানোর ক্ষেত্রে (I / O ছাড়াই) প্রচলিত শেলের তুলনায় কয়েক গুণ বেশি গতি ছিল।

    তবে, আপনি যদি শেলটি ব্যবহার করেন তবে বাহ্যিক কমান্ডের পরিবর্তে শেলের বিল্টিন ফাংশন ব্যবহার করুন। এখানে আপনি ব্যবহার করছেন exprযা আমার সিস্টেমে পাওয়া কোন শেলের মধ্যে অন্তর্নির্মিত নয় তবে মানক গাণিতিক সম্প্রসারণের সাথে এটি প্রতিস্থাপন করা যেতে পারে। যেমন ইনক্রিমেন্টের i=$((i+1))পরিবর্তে । শেষ উদাহরণে আপনার ব্যবহার মানক প্যারামিটার বিস্তারের সাথে প্রতিস্থাপনযোগ্যও হতে পারে।i=$(expr $i + 1)icut

    আরও দেখুন: পাঠ্যকে প্রক্রিয়াজাত করতে শেল লুপ ব্যবহার করা খারাপ অভ্যাস হিসাবে বিবেচনা করা হয় কেন?

আপনার প্রশ্নের ক্ষেত্রে # 1 এবং # 2 পদক্ষেপগুলি প্রয়োগ করা উচিত।


12
# 0, আপনার সম্প্রসারণের উদ্ধৃতি দিন :-)
কুসালানন্দ

8
এটি নয় যে awkলুপগুলি শেল লুপগুলির চেয়ে আরও ভাল বা খারাপ arily এটি হ'ল শেলটি কমান্ডগুলি চালনার ক্ষেত্রে এবং প্রক্রিয়াগুলিতে এবং থেকে ইনপুট এবং আউটপুটকে নির্দেশিত করার ক্ষেত্রে এবং স্পষ্টভাবে বরং সমস্ত কিছুতে আঁকড়ে রাখা ভাল; সরঞ্জামের মত যখন awkহয় চমত্কার কারণ যে কী শেল এবং সরঞ্জামের মত, টেক্সট ডাটা প্রক্রিয়াকরণের সময়ে awkপ্রথম স্থানে জন্য (যথাক্রমে) তৈরি করা হয়।
ডোপঘোটি

2
@ দোপগোতি, শেলগুলি উদ্দেশ্যমূলকভাবে ধীর বলে মনে হচ্ছে। কিছু খুব সরল যখন লুপগুলি মনে হয় তার dashচেয়ে 25 গুণ কম গতিতে দেখা যায় gawkএবং dashএটি আমার সবচেয়ে দ্রুততম শেল ছিল ...
ইলক্কাচু

1
@ জো, এটি :) dashএবং busyboxসমর্থন করে না (( .. ))- আমি মনে করি এটি একটি মানহীন এক্সটেনশন। ++এছাড়াও স্পষ্টভাবে উল্লেখ হিসাবে প্রয়োজন হয় না, তাই যতটা আমি বলতে পারেন, যেমন i=$((i+1))বা : $(( i += 1))নিরাপদ বেশী।
ইলকচাচু

1
পুনরায় "আরও সময় চিন্তা" : এটি একটি গুরুত্বপূর্ণ বিষয়টিকে অবহেলা করে। এটি কতবার চালিত হয় এবং কতজন ব্যবহারকারীর জন্য? যদি কোনও প্রোগ্রাম 1 সেকেন্ড নষ্ট করে, যা প্রোগ্রামার দ্বারা এটি 30 মিনিটের জন্য চিন্তা করে ঠিক করা যেতে পারে তবে এটির অপচয় হতে পারে যদি কেবলমাত্র একজন ব্যবহারকারী যিনি একবার এটি চালাচ্ছেন। অন্যদিকে যদি মিলিয়ন ব্যবহারকারী থাকে তবে তা মিলিয়ন সেকেন্ড বা ব্যবহারকারীর 11 দিন। কোডটি যদি এক মিলিয়ন ব্যবহারকারীদের এক মিনিট নষ্ট করে তবে এটি ব্যবহারকারীর সময় প্রায় 2 বছর
এজিসি

13

আমি কেবল এই উত্তরে কিছু সাধারণ পরামর্শ দিতে যাচ্ছি, এবং মানদণ্ড নয়। পারফরম্যান্স সম্পর্কে নির্ভরযোগ্য প্রশ্নের উত্তর দেওয়ার একমাত্র উপায় বেঞ্চমার্ক। আপনি যে পরিমাণ ডেটা ম্যানিপুলেট করছেন এবং আপনি কতবার এই অপারেশনটি সম্পাদন করছেন তা আপনি বলছেন না , তাই কোনও কার্যকর বেঞ্চমার্ক করার উপায় নেই। 10 টি আইটেমের জন্য কী বেশি দক্ষ এবং 1000000 আইটেমগুলির জন্য আরও কার্যকর কী তা প্রায়শই এক রকম হয় না।

থাম্বের একটি সাধারণ নিয়ম হিসাবে, খাঁটি শেল কনস্ট্রাক্টস সহ কিছু করার চেয়ে বাহ্যিক আদেশগুলি চাওয়া আরও ব্যয়বহুল, যতক্ষণ না খাঁটি শেল কোড কোনও লুপকে জড়িত না করে। অন্যদিকে, একটি শেল লুপ যা একটি বৃহত স্ট্রিং বা প্রচুর পরিমাণে স্ট্রিং দিয়ে পুনরাবৃত্তি হয় বিশেষ-উদ্দেশ্যে সরঞ্জামটির একটি অনুরোধের চেয়ে ধীর হতে পারে। উদাহরণস্বরূপ, আপনার লুপটি চাওয়াটি cutঅভ্যাসের ক্ষেত্রে লক্ষণীয়ভাবে ধীর হতে পারে, তবে আপনি যদি একটি একক অনুরোধ দিয়ে পুরো কাজটি করার উপায় খুঁজে cutপান যা শেলের মধ্যে স্ট্রিং ম্যানিপুলেশন সহ একই জিনিসটি করার চেয়ে দ্রুত হতে পারে।

মনে রাখবেন যে কাটঅফ পয়েন্ট সিস্টেমের মধ্যে অনেকগুলি পৃথক হতে পারে। এটি কার্নেলের উপর নির্ভর করে, কার্নেলের শিডিয়ুলার কীভাবে কনফিগার করা যায়, বাহ্যিক এক্সিকিউটেবলগুলি সমন্বিত ফাইল সিস্টেমে, এই মুহুর্তে CPU বনাম মেমরির চাপের পরিমাণ এবং অন্যান্য অনেকগুলি বিষয়গুলির উপর নির্ভর করতে পারে।

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

আপনি ব্যাশ ব্যবহার করছেন বলে মনে হচ্ছে, যেহেতু আপনি ব্যাশ নির্মাণগুলি ব্যবহার করছেন যা sh এ নেই in তাহলে কেন পৃথিবীতে আপনি একটি অ্যারে ব্যবহার করবেন না? একটি অ্যারে হ'ল সর্বাধিক প্রাকৃতিক সমাধান এবং এটি খুব দ্রুততম হওয়ার সম্ভাবনাও রয়েছে। নোট করুন যে অ্যারে সূচকগুলি 0 থেকে শুরু হয়।

list=(1 2 3 5 9 8 6 90 84 9 3 2 15 75 55)
for ((count = 0; count += 3; count < ${#list[@]})); do
  echo "${list[$count]}"
done

আপনি স্ক ব্যবহার করলে আপনার স্ক্রিপ্টটি আরও দ্রুত হতে পারে, যদি আপনার সিস্টেমে বাশের shপরিবর্তে ড্যাশ বা ksh থাকে। আপনি যদি sh ব্যবহার করেন, আপনি নামযুক্ত অ্যারে পাবেন না, তবে আপনি এখনও অবস্থানীয় পরামিতিগুলির একটি অ্যারে পাবেন যা আপনি সেট করতে পারেন set। রানটাইম পর্যন্ত জানা যায় না এমন অবস্থানে এমন কোনও উপাদান অ্যাক্সেস করার জন্য আপনাকে ব্যবহার করতে হবে eval(জিনিসগুলি যথাযথভাবে উদ্ধৃত করার ক্ষেত্রে যত্ন নিন!)।

# List elements must not contain whitespace or ?*\[
list='1 2 3 5 9 8 6 90 84 9 3 2 15 75 55'
set $list
count=1
while [ $count -le $# ]; do
  eval "value=\${$count}"
  echo "$value"
  count=$((count+1))
done

আপনি যদি কেবল একবারে অ্যারে অ্যাক্সেস করতে চান এবং বাম থেকে ডানে বাম দিকে চলে যাচ্ছেন (কিছু মান বাদ দিচ্ছেন), আপনি shiftভেরিয়েবল সূচকগুলির পরিবর্তে ব্যবহার করতে পারেন ।

# List elements must not contain whitespace or ?*\[
list='1 2 3 5 9 8 6 90 84 9 3 2 15 75 55'
set $list
while [ $# -ge 1 ]; do
  echo "$1"
  shift && shift && shift
done

কোন পদ্ধতির দ্রুত শেল এবং উপাদানগুলির সংখ্যার উপর নির্ভর করে।

আরেকটি সম্ভাবনা স্ট্রিং প্রসেসিং ব্যবহার করা। অবস্থানগত পরামিতি ব্যবহার না করার সুবিধা রয়েছে, তাই আপনি এগুলি অন্য কোনও কিছুর জন্য ব্যবহার করতে পারেন। এটি প্রচুর পরিমাণে ডেটার জন্য ধীর হয়ে উঠবে, তবে অল্প পরিমাণে ডেটার জন্য এটি একটি উল্লেখযোগ্য পার্থক্য করার সম্ভাবনা কম unlikely

# List elements must be separated by a single space (not arbitrary whitespace)
list='1 2 3 5 9 8 6 90 84 9 3 2 15 75 55'
while [ -n "$list" ]; do
  echo "${list% *}"
  case "$list" in *\ *\ *\ *) :;; *) break;; esac
  list="${list#* * * }"
done

" অন্যদিকে, একটি বৃহত স্ট্রিং বা প্রচুর পরিমাণে স্ট্রিং দিয়ে পুনরাবৃত্তি হওয়া একটি শেল লুপটি সম্ভবত কোনও বিশেষ-উদ্দেশ্য সরঞ্জামের একটি অনুরোধের চেয়ে ধীর হতে পারে " তবে যদি সেই সরঞ্জামটির মধ্যে ফাঁকের মতো লুপ থাকে তবে কী হবে? @ আইক্কাচু বলেছিলেন যে খালি লুপগুলি দ্রুত, তবে আপনি কি বলতে পারবেন যে <1000 ক্ষেত্রটি দিয়ে পুনরাবৃত্তি হবে, দ্রুত লুপগুলির সুবিধা আধ্যাত্মিক কলিং ব্যয়কে ছাড়িয়ে যাবে না কারণ এটি বাহ্যিক কমান্ড (ধরে নিলাম শেলের মধ্যেও আমি একই কাজ করতে পারি) শুধুমাত্র অন্তর্নির্মিত কমান্ড ব্যবহার করে লুপগুলি)?
লেবি উজোদাইক

@ লেভিউউজাইক দয়া করে আমার উত্তরের প্রথম অনুচ্ছেদটি পুনরায় পড়ুন।
গিলস 'অশুভ হওয়া বন্ধ করুন'

আপনি নিজের তৃতীয় উদাহরণের shift && shift && shiftসাথে এটিও প্রতিস্থাপন করতে পারেন shift 3- আপনি যে শেলটি ব্যবহার করছেন তা যদি সমর্থন না করে।
জো

2
@ জো আসলে, না। shift 3খুব অল্প যুক্তি থাকলে ব্যর্থ হত। আপনি ভালো কিছু প্রয়োজন চাইif [ $# -gt 3 ]; then shift 3; else set --; fi
গিলেজ 'SO- স্টপ হচ্ছে মন্দ'

3

awkআপনি যদি আপনার সমস্ত প্রসেসিং আওক স্ক্রিপ্টের অভ্যন্তরে করতে পারেন তবে এটি দুর্দান্ত পছন্দ । অন্যথায়, আপনি খালি আউটপুটটি অন্যান্য ইউটিলিটিগুলিতে পাইপিং শেষ করে, এর কার্যকারিতা লাভকে নষ্ট করে দেন awk

bashঅ্যারের উপরে পুনরাবৃত্তিটিও দুর্দান্ত, যদি আপনি অ্যারের ভিতরে নিজের পুরো তালিকাটি ফিট করতে পারেন (যা আধুনিক শেলগুলির জন্য সম্ভবত একটি গ্যারান্টি) এবং আপনি অ্যারে সিনট্যাক্স জিমন্যাস্টিকগুলিকে কিছু মনে করেন না।

তবে, একটি পাইপলাইন পদ্ধতির:

xargs -n3 <<< "$list" | while read -ra a; do echo $a; done | grep 9

কোথায়:

  • xargs তিনটি ব্যাচগুলিতে শ্বেতক্ষেত্র-বিচ্ছিন্ন তালিকাটিকে দলবদ্ধ করে, প্রতিটি নতুন-লাইন পৃথক করে
  • while read সেই তালিকাটি গ্রহন করে এবং প্রতিটি গ্রুপের প্রথম কলাম আউটপুট করে
  • grep প্রথম কলামটি ফিল্টার করে (মূল তালিকার প্রতিটি তৃতীয় অবস্থানের সাথে সম্পর্কিত)

আমার মতে বোধগম্যতা উন্নত করে। লোকেরা ইতিমধ্যে জানে যে এই সরঞ্জামগুলি কী করে, তাই বাম থেকে ডানদিকে পড়া সহজ এবং কী ঘটছে সে সম্পর্কে যুক্তিযুক্ত। এই পদ্ধতির এছাড়াও স্পষ্ট দৈর্ঘ্য ( -n3) এবং ফিল্টার প্যাটার্ন ( 9) ডকুমেন্ট , তাই এটি পরিবর্তনশীল করা সহজ:

count=3
find=9
xargs -n "$count" <<< "$list" | while read -ra a; do echo $a; done | grep "$find"

যখন আমরা "দক্ষতা" এর প্রশ্ন জিজ্ঞাসা করি, তখন "মোট আজীবন দক্ষতা" সম্পর্কে অবশ্যই চিন্তা করুন। এই গণনাটিতে কোডটি কার্যকর রাখার জন্য রক্ষণাবেক্ষণকারীদের প্রচেষ্টা অন্তর্ভুক্ত রয়েছে এবং আমরা গো-মাংস-ব্যাগগুলি পুরো অপারেশনের মধ্যে সবচেয়ে কম দক্ষ মেশিন।


2

সম্ভবত এই?

cut -d' ' -f1,4,7,10,13 <<<$list
1 5 6 9 15

দুঃখিত, আমি এর আগে পরিষ্কার ছিলাম না, তবে আমি তালিকার দৈর্ঘ্য না জেনে positions অবস্থানগুলিতে নম্বর পেতে সক্ষম হতে চাই। তবে ধন্যবাদ, আমি ভুলে গিয়েছিলাম যে এটি করতে পারে।
লেবি উজোদিকে

1

আপনি দক্ষ হতে চাইলে শেল কমান্ডগুলি ব্যবহার করবেন না। নিজেকে পাইপ, পুনর্নির্দেশগুলি, বিকল্পগুলি ইত্যাদি এবং প্রোগ্রামগুলিতে সীমাবদ্ধ করুন। এজন্য xargsএবং parallelইউটিলিটিগুলি বিদ্যমান - কারণ লুপগুলি অকার্যকর এবং খুব ধীর হয়। কেবল শেষ সমাধান হিসাবে বাশ লুপগুলি ব্যবহার করুন।

list="1 ant bat 5 cat dingo 6 emu fish 9 gecko hare 15 i j"
if 
    <<<"$list" tr -d -s '[0-9 ]' | 
    tr -s ' ' | tr ' ' '\n' | 
    grep -q -x '9'
then
    found=true
else 
    found=false
fi
echo ${found} 

তবে আপনার সম্ভবত ভাল কিছুটা দ্রুত হওয়া উচিত awk


দুঃখিত আমি এর আগে পরিষ্কার ছিলাম না, তবে আমি এমন একটি সমাধান খুঁজছিলাম যা কেবলমাত্র তালিকার তাদের অবস্থানের ভিত্তিতে মানগুলি বের করতে সক্ষম হবে। আমি কেবলমাত্র মূল তালিকাটি তৈরি করেছিলাম কারণ আমি এটি চেয়েছিলাম যে মানগুলি আমি চেয়েছিলাম তা সুস্পষ্ট হোক।
লেভি উজোদিকে

1

আমার মতে স্পষ্ট সমাধান (এবং সম্ভবত সবচেয়ে পারফরম্যান্টও) হ'ল আরএস এবং ওআরএস অ্যাড ভেরিয়েবলগুলি ব্যবহার করা:

awk -v RS=' ' -v ORS=' ' 'NR % 3 == 1' <<< "$list"

1
  1. ব্যবহার গনুহ sed এবং POSIX শেল স্ক্রিপ্ট :

    echo $(printf '%s\n' $list | sed -n '1~3p')
  2. অথবা সঙ্গে bashএর পরামিতি বিকল্প সহ :

    echo $(sed -n '1~3p' <<< ${list// /$'\n'})
  3. নন- জিএনইউ ( যেমন পসিক্স )sed , এবং bash:

    sed 's/\([^ ]* \)[^ ]* *[^ ]* */\1/g' <<< "$list"

    বা তার বেশি portably, উভয় ব্যবহার POSIX sed এবং শেল স্ক্রিপ্ট:

    echo "$list" | sed 's/\([^ ]* \)[^ ]* *[^ ]* */\1/g'

এর যে কোনও একটির আউটপুট:

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