বাশে গল্ফ করার টিপস


55

বাশে গল্ফ করার জন্য আপনার কাছে কোন সাধারণ টিপস রয়েছে? আমি এমন ধারণাগুলি সন্ধান করছি যা সাধারণভাবে গল্ফ সমস্যার ক্ষেত্রে কোড প্রয়োগ করা যেতে পারে যা কমপক্ষে কিছুটা নির্দিষ্টভাবে বাশের ক্ষেত্রে নির্দিষ্ট (যেমন "মন্তব্যগুলি সরান" কোনও উত্তর নয়)। দয়া করে উত্তর প্রতি একটি টিপ পোস্ট করুন।

উত্তর:


36

Undocumented , কিন্তু উত্তরাধিকারেরshপিছনের সামঞ্জস্যেরজন্য আমি যে সংস্করণে চলেছি সেগুলিতে কাজ করে:

forলুপগুলি { }পরিবর্তে আপনাকে ব্যবহার করতে দেয় do done। যেমন প্রতিস্থাপন:

for i in {1..10};do echo $i; done

সঙ্গে:

for i in {1..10};{ echo $i;}

শেলটি কী shএবং শেলটি এই forসিনট্যাক্সটিকে কী অনুমতি দেয় ? এটি স্পষ্টভাবে অনুমতি দেওয়া হয় zsh
মাইকসার্ভ

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

আহ ... csh, সম্ভবত - তারা সেই শেলটিতে এভাবেই কাজ করেছিল।
মাইকজার্ভ

উপায় দ্বারা, এ ksh93উপরে জিনিস হতে পারে: ;{1..10}, এবং bash:printf %s\\n {1..10}
mikeserv

1
for((;i++<10)){ echo $i;}এর চেয়ে সংক্ষিপ্তfor i in {1..10};{ echo $i;}
ইভান ਕੁਲরে

29

$[…]পরিবর্তে গাণিতিক সম্প্রসারণের জন্য $((…)):

bash-4.1$ echo $((1+2*3))
7

bash-4.1$ echo $[1+2*3]
7

পাটিগণিত বিস্তারে ব্যবহার করবেন না $:

bash-4.1$ a=1 b=2 c=3

bash-4.1$ echo $[$a+$b*$c]
7

bash-4.1$ echo $[a+b*c]
7

অঙ্কিত অ্যারে সাবস্ক্রিপ্টগুলিতে গাণিতিক সম্প্রসারণ করা হয়, সুতরাং $সেখানেও ব্যবহার করবেন না :

bash-4.1$ a=(1 2 3) b=2 c=3

bash-4.1$ echo ${a[$c-$b]}
2

bash-4.1$ echo ${a[c-b]}
2

পাটিগণিত বিস্তারে ব্যবহার করবেন না ${…}:

bash-4.1$ a=(1 2 3)

bash-4.1$ echo $[${a[0]}+${a[1]}*${a[2]}]
7

bash-4.1$ echo $[a[0]+a[1]*a[2]]
7

প্রতিস্থাপন while((i--)), যা আমার সাথে কাজ করে while[i--]বা while $[i--]কাজ করে না। জিএনইউ বাশ, সংস্করণ 4.3.46 (1)
গ্লেন র্যান্ডার্স-

1
সঠিক, @ গ্লেনর্যান্ডার্স-পেহারসন। কাজ করার কথা নয়।
manatwork

y=`bc<<<"($x*2.2)%10/1"`... bcঅ-পূর্ণসংখ্যার গণনার জন্য ব্যবহারের উদাহরণ ... নোটটি /1শেষের দিকে ফলাফলের দশমিককে একটি পূর্ণসংখ্যায় ছাড়ে।
রোব্লোগিক

s=$((i%2>0?s+x:s+y))... ব্যাশ পাটিগণিতে টের্নারি অপারেটর ব্যবহারের উদাহরণ। এটি এর চেয়ে কম if..then..elseবা[ ] && ||
রোব্লোগিক

1
@ মান্যাটওয়ার্ক ধন্যবাদ তারা অবশ্যই এটি সরিয়ে ফেলেছে। আমি চালু GNU bash, version 5.0.2(1)-release (x86_64-apple-darwin16.7.0)এবং এটি আমার মধ্যে নেই
জোনাহ

19

কোনও ফাংশন সংজ্ঞায়িত করার স্বাভাবিক, দীর্ঘ এবং বিরক্তিকর উপায়

f(){ CODE;}

যেহেতু এই লোকটি জানতে পেরেছে, আপনার একেবারে ঠিক আগে জায়গা CODEএবং তারপরে সেমিকোলন প্রয়োজন।

এটি একটি ছোট কৌশল যা আমি @ ডিজিটাল ট্রামুমার কাছ থেকে শিখেছি :

f()(CODE)

এটি দুটি অক্ষর সংক্ষিপ্ত এবং এটি ঠিক পাশাপাশি কাজ করে তবে শর্ত হয় যে ফাংশনটি ফিরে আসার পরে আপনার ভেরিয়েবলের মানগুলিতে কোনও পরিবর্তন আনতে হবে না ( বন্ধনীগুলি একটি সাবশেলে শরীর চালায় )।

@ জিমি ২৩০১৩ মন্তব্যগুলিতে যেমন উল্লেখ করেছেন, এমনকি বন্ধনীগুলিও অপ্রয়োজনীয় হতে পারে।

ব্যাশ রেফারেন্স ম্যানুয়াল দেখায় নিম্নরূপ কার্যাবলী সংজ্ঞায়িত করা যায় যে:

name () compound-command [ redirections ]

অথবা

function name [()] compound-command [ redirections ]

একটি যৌগিক আদেশ হতে পারে:

  • একটি looping: until, whileবাfor
  • একটি শর্তাধীন কনস্ট্রাক্ট: if, case, ((...))অথবা[[...]]
  • দলবদ্ধ কমান্ড: (...)বা{...}

তার মানে নীচের সমস্তগুলি বৈধ:

$ f()if $1;then $2;fi
$ f()($1&&$2)
$ f()(($1))                # This one lets you assign integer values

এবং আমি একটি স্তন্যপায়ী বন্ধনী হিসাবে একটি স্তন্যপায়ী বন্ধনী ব্যবহার করেছি ...


2
মনে রাখবেন যে আপনি f()while ... f()if ...এবং অন্যান্য যৌগিক আদেশগুলিও ব্যবহার করতে পারেন ।
জিমি 23013

এটি আমাকে অবাক করেছিল কারণ আমি ভেবেছিলাম f()CODEআইনী। দেখা যাচ্ছে যে f()echo hipdksh এবং zsh এ বৈধ, তবে ব্যাশে নয়।
কর্নিগ

1
এটির বিশেষভাবে দরকারী ডাব্লু / forযেহেতু এটি অবস্থানের ডিফল্ট: f()for x do : $x; done;set -x *;PS4=$* f "$@"বা কিছুতে।
মাইকজার্ভ

16

:হ'ল একটি আদেশ যা কিছুই করে না, তার প্রস্থান স্থিতি সর্বদা সফল হয়, তাই এটি পরিবর্তে ব্যবহার করা যেতে পারে true


সাবসেল ব্যবহার এবং পাইপিং করা প্রায় একই সংখ্যক বাইট ব্যবহার করবে তবে এটি পাইপ করা আরও ব্যবহারিক হবে।
ckjbgames

5
আপনি যখন করবেন তা বাদে:(){:|:}

14

আরও টিপস

  1. টার্নারি অপারেটর, ((test)) && cmd1 || cmd2বা [ test ] && cmd1 || cmd2যতটা সম্ভব অপব্যবহার করুন ।

    উদাহরণ (দৈর্ঘ্যের গণনা সর্বদা শীর্ষ রেখা বাদ দেয়):

    t="$something"
    if [ $t == "hi" ];then
    cmd1
    cmd2
    elif [ $t == "bye" ];then
    cmd3
    cmd4
    else
    cmd5
    if [ $t == "sup" ];then
    cmd6
    fi
    fi
    

    কেবলমাত্র টের্নারি অপারেটরগুলি ব্যবহার করে, এটি সহজেই সংক্ষিপ্ত করা যেতে পারে:

    t="$something"
    [ $t == "hi" ]&&{
    cmd1;cmd2
    }||[ $t == "bye" ]&&{
    cmd3;cmd4
    }||{
    cmd5
    [ $t == "sup" ]&&cmd6
    }
    

    যেমন হিসাবে nyuszika7h মন্তব্যগুলিতে উল্লেখ করেছেন, এই নির্দিষ্ট উদাহরণটি আরও ব্যবহার করে আরও ছোট করা যেতে পারে case:

    t="$something"
    case $t in "hi")cmd1;cmd2;;"bye")cmd3;cmd4;;*)cmd5;[ $t == "sup" ]&&cmd6;esac
    
  2. এছাড়াও, যতটা সম্ভব বন্ধনীগুলির জন্য বন্ধনী পছন্দ করুন। যেহেতু প্রথম বন্ধনীগুলি একটি মেটাচার্যাক্টর, এবং একটি শব্দ নয়, তাদের কোনও প্রসঙ্গে স্থানের প্রয়োজন হয় না। এর অর্থ হ'ল সম্ভব সাবস্কেলে যতগুলি কমান্ড চালানো সম্ভব, কারণ কোঁকড়ানো ধনুর্বন্ধনী (যেমন {এবং }) সংরক্ষিত শব্দ, মেটা-অক্ষর নয়, এবং সঠিকভাবে পার্স করার জন্য উভয় পক্ষের সাদা অংশ থাকতে হবে, তবে মেটা-অক্ষরগুলি নেই। আমি ধরে নিলাম যে আপনি এখনই জানেন যে সাবশেলগুলি পিতামন্ত্রের পরিবেশকে প্রভাবিত করে না, তাই ধরে নিই যে সমস্ত উদাহরণ কমান্ডগুলি নিরাপদে একটি সাবশেলে চালানো যেতে পারে (যা কোনও ক্ষেত্রেই সাধারণ নয়), আপনি উপরের কোডটি সংক্ষিপ্ত করতে পারবেন :

    t=$something
    [ $t == "hi" ]&&(cmd1;cmd2)||[ $t == "bye" ]&&(cmd3;cmd4)||(cmd5;[ $t == "sup" ]&&cmd6)
    

    এছাড়াও, যদি আপনি না পারেন তবে প্যারেন্থিস ব্যবহার করে কিছুটা এটিকে ছোট করে দিতে পারে। একটি জিনিস মনে রাখবেন তা হ'ল এটি কেবল পূর্ণসংখ্যার জন্য কাজ করে, যা এ উদাহরণের উদ্দেশ্যে এটি অকেজো করে তোলে (তবে এটি -eqপূর্ণসংখ্যার জন্য ব্যবহার করার চেয়ে অনেক ভাল )।

  3. আরও একটি বিষয়, যেখানে সম্ভব উদ্ধৃতিগুলি এড়িয়ে চলুন। উপরের পরামর্শটি ব্যবহার করে, আপনি আরও এটিকে ছোট করতে পারেন। উদাহরণ:

    t=$something
    [ $t == hi ]&&(cmd1;cmd2)||[ $t == bye ]&&(cmd3;cmd4)||(cmd5;[ $t == sup ]&&cmd6)
    
  4. পরীক্ষার শর্তে, কয়েকটি ব্যাতিক্রম দিয়ে যতটা সম্ভব ডাবল বন্ধনীগুলিতে একক বন্ধনী পছন্দ করুন। এটি নিখরচায় দুটি চরিত্র হ্রাস করে তবে কিছু ক্ষেত্রে এটি এতটা দৃust় নয় (এটি একটি বাশ এক্সটেনশান - উদাহরণের জন্য নীচে দেখুন)। এছাড়াও, দ্বিগুণের পরিবর্তে একক সমতুল্য যুক্তি ব্যবহার করুন। এটি বাদ দেওয়ার জন্য একটি মুক্ত চরিত্র।

    [[ $f == b ]]&&: # ... <-- Bad
    [ $f == b ]&&: # ... <-- Better
    [ $f = b ]&&: # ... <-- Best.  word splits and pathname-expands the contents of $f.  Esp. bad if it starts with -
    

    এই সতর্কতা নোট করুন, বিশেষত নাল আউটপুট বা একটি অপরিজ্ঞাত ভেরিয়েবল পরীক্ষা করার জন্য:

    [[ $f ]]&&:    # double quotes aren't needed inside [[, which can save chars
    [ "$f" = '' ]&&: <-- This is significantly longer
    [ -n "$f" ]&&:
    

    সমস্ত প্রযুক্তিগত ক্ষেত্রে, এই নির্দিষ্ট উদাহরণটি দিয়ে সর্বোত্তম হবে case... in:

    t=$something
    case $t in hi)cmd1;cmd2;;bye)cmd3;cmd4;;*)cmd5;[ $t == sup ]&&cmd6;esac
    

সুতরাং, এই পোস্টের নৈতিক এটি:

  1. বুলিয়ান অপারেটরদের যথাসম্ভব অপব্যবহার করুন এবং সর্বদাif / if-else/ ইত্যাদির পরিবর্তে সেগুলি ব্যবহার করুন । নির্মান।
  2. যথাক্রমে বন্ধনীগুলি ব্যবহার করুন এবং সাবশেলে যতটা সম্ভব বিভাগগুলি চালান কারণ বন্ধনীগুলি মেটা-অক্ষর এবং সংরক্ষিত শব্দ নয়।
  3. শারীরিকভাবে যতটা সম্ভব উদ্ধৃতিগুলি এড়িয়ে চলুন।
  4. দেখুন case... in, যেহেতু এটি বেশ কয়েকটি বাইট সংরক্ষণ করতে পারে, বিশেষত স্ট্রিং মেলিংয়ে।

পিএস: এখানে প্রসঙ্গ নির্বিশেষে বাশে স্বীকৃত মেটা-অক্ষরের একটি তালিকা রয়েছে (এবং শব্দ পৃথক করতে পারে):

&lt; &gt; ( ) ; & | &lt;space&gt; &lt;tab&gt;

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

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


বলার জন্য দুঃখিত, তবে আপনার কিছু গুরুতর ত্রুটি রয়েছে। [ $t=="hi" ]এটি সর্বদা 0 তে মূল্যায়ন করবে, যেমনটি পার্স করা হয় [ -n "STRING" ](($t=="hi"))যতক্ষণ না ar t এর অ-সংখ্যাসূচক মান থাকে ততক্ষণ সর্বদা 0 তে মূল্যায়ন করবে কারণ পাটিগণিতের মূল্যায়নে স্ট্রিংগুলি পূর্ণসংখ্যায় বাধ্য করা হয়। কিছু পরীক্ষার কেস: পেস্টবিন.
com

@ মানাত্কার এই ধরার জন্য ধন্যবাদ। আমি সেই অনুযায়ী আপডেট করব।
ইসিয়া মিডোস

একটি ব্যবহার caseএখানে সংক্ষিপ্ত হবে। এছাড়াও, আপনার আগে কোনও স্থানের প্রয়োজন হবে না }তবে আপনি পরে করবেন {
nyuszika7h

1
এর =চেয়ে কম শক্ত হবে কেন ==? =POSIX দ্বারা আদেশ দেওয়া হয়, ==না।
ডেনিস

1
প্রশ্নটিতে প্রতি উত্তরের জন্য একটি টিপ জিজ্ঞাসা করা হচ্ছে ...
টবি স্পিড

7

বদলে grep -E, grep -F, grep -r, ব্যবহার egrep, fgrep, rgrep, দুই অক্ষর সংরক্ষণ। সংক্ষিপ্তগুলি হ্রাস করা হয়েছে তবে ঠিক আছে।

(আপনি উত্তরে প্রতি টিপস চেয়েছিলেন!)


1
এটা খুব খারাপ, কোন ব্যাপার Pgrepজন্য grep -P। যদিও আমি দেখছি এটি কীভাবে সহজেই বিভ্রান্ত হতে পারে pgrep, যা প্রক্রিয়াগুলি অনুসন্ধানে ব্যবহৃত হয়।
nyuszika7h 19

1
@ nyuszika7h আমি ব্যক্তিগতভাবে grep -oঅনেক কিছু ব্যবহার করি

এটি স্থান সহ 3 টি সংরক্ষণ করবে না?
ckjbgames

7

একটি অ্যারের এলিমেন্ট 0 কেবলমাত্র ভেরিয়েবল নামের সাথে অ্যাক্সেস করা যেতে পারে, পাঁচটি বাইট সাশ্রয়ীভাবে 0 এর সূচক নির্দিষ্ট করে তুলতে সঞ্চয় করে:

$ a=(code golf)
$ echo ${a[0]}
code
$ echo $a
code
$ 

7

যদি আপনাকে পাইপলাইনে পরবর্তী প্রক্রিয়ার STDIN এ ভেরিয়েবলের সামগ্রীটি পাস করতে হয় তবে ভেরিয়েবলটি পাইপলাইনে প্রতিধ্বনিত করা সাধারণ বিষয়। তবে আপনি <<< এখানে স্ট্রিং দিয়ে একই জিনিসটি অর্জন করতে পারেন :

$ s="code golf"
$ echo "$s"|cut -b4-6
e g
$ cut -b4-6<<<"$s"
e g
$ 

2
যেহেতু আমরা গল্ফ করছি s=code\ golf, echo $s|এবং <<<$s(যে দুটি পুনরাবৃত্তি স্পেস ইত্যাদি নেই শুধুমাত্র কারণ দুটি পরবর্তী কাজগুলি মনে রাখবেন)।
ডেনিস

6

এড়িয়ে চলুন $( ...command... ), এমন একটি বিকল্প রয়েছে যা একটি চর সংরক্ষণ করে এবং একই কাজ করে:

` ...command... `

9
কখনও কখনও $( )প্রয়োজন হয় যদি আপনার কমান্ড বিকল্পগুলি নেস্ট করে থাকে; অন্যথায় আপনাকে অভ্যন্তর থেকে বাঁচতে হবে``
ডিজিটাল ট্রমা

1
এই প্রযুক্তিগতভাবে বিভিন্ন কাজ করে, উদাহরণস্বরূপ, $()আমি যখন আমার মেশিনে scpলক্ষ্য মেশিনের পরিবর্তে বিকল্পটি চালাতে চেয়েছিলাম তখন তার পরিবর্তে আমাকে ব্যাকটিকগুলি ব্যবহার করতে হয়েছিল । বেশিরভাগ ক্ষেত্রে তারা অভিন্ন।
আন্ডারগ্রাউন্ডোমোনাইল

2
@underlandmonorail: আপনার কখনও ব্যাকটিক্স লাগবে না । তারা কিছু করতে পারে, $()আপনি যদি জিনিসগুলিকে যথাযথভাবে উদ্ধৃত করেন তবে করতে পারেন। (যদি না এমন কিছু বেঁচে থাকার জন্য আপনার কমান্ডের প্রয়োজন $না হয় যা ব্যাকটিক্স নয় তবে)। তাদের ভিতরে জিনিস উদ্ধৃত করার কিছু সূক্ষ্ম পার্থক্য আছে। mywiki.wooledge.org/BashFAQ/082 কিছু পার্থক্য ব্যাখ্যা করে। আপনি গল্ফ না করলে ব্যাকটিক্স কখনও ব্যবহার করবেন না।
পিটার কর্ডেস

@ পিটারকর্ডস আমি নিশ্চিত যে একটি উপায় ছিল তবে আমি চেষ্টা করেছিলাম সেই সময়ে কার্যকর সমস্ত কিছুই কার্যকর হয়নি। এমনকি ব্যাকটিক্স সেরা সমাধান না হলেও, আমি তাদের সম্পর্কে জানতাম বলে আমি আনন্দিত কারণ এটি ছিল আমার একমাত্র সমাধান। ¯ \ _ (ツ) _ / ¯
আন্ডারগ্রাউন্ডোমোরিয়েল

@ ডিজিটাল ট্রুমা বাসা বাঁধার নমুনা: echo `bc <<<"\`date +%s\`-12"`... (মন্তব্যটিতে ব্যাকটিকযুক্ত নমুনা পোস্ট করা শক্ত!))
এফ হৌরি

6

ifগ্রুপ কমান্ড ব্যবহার করুন

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

আপনার যদি একটি কমান্ড গোষ্ঠী থাকে যা একটি দিয়ে শেষ হয় if, এর মতো:

a&&{ b;if c;then d;else e;fi;}
a&&(b;if c;then d;else e;fi)

ifপরিবর্তে শর্তের আগে আপনি কমান্ডগুলি মোড়ানো করতে পারেন :

a&&if b;c;then d;else e;fi

বা যদি আপনার ফাংশনটি একটি দিয়ে শেষ হয় if:

f(){ a;if b;then c;else d;fi;}

আপনি বন্ধনীগুলি মুছে ফেলতে পারেন:

f()if a;b;then c;else d;fi

1
আপনি [test] && $if_true || $elseএই ফাংশনগুলিতে টার্নারি অপারেটরটি ব্যবহার করতে পারেন এবং কিছু বাইট সংরক্ষণ করতে পারেন ।
ckjbgames

এছাড়াও, আপনার চারপাশের স্পেসগুলির প্রয়োজন নেই &&এবং||
রোব্লজিক

6

(( ... ))শর্তের জন্য পাটিগণিত ব্যবহার করুন

আপনি প্রতিস্থাপন করতে পারে:

if [ $i -gt 5 ] ; then
    echo Do something with i greater than 5
fi

দ্বারা

if((i>5));then
    echo Do something with i greater than 5
fi

(দ্রষ্টব্য: এর পরে কোনও স্থান নেই if)

অথবা এমনকি

((i>5))&&{
    echo Do something with i greater than 5
}

... অথবা যদি কেবল একটি আদেশ হয়

((i>5))&&echo Echo or do something with i greater than 5

আরও: পাটিগণিত গঠনে পরিবর্তনশীল সেটিংটি লুকান:

((i>5?c=1:0))&&echo Nothing relevant there...
# ...
((c))&&echo Doing something else if i was greater than 5

বা একই

((c=i>5?c=0,1:0))&&echo Nothing relevant there...
# ...
((c))&&echo Doing something else if i was greater than 5

... যেখানে যদি i> 5 হয়, তবে সি = 1 (0% নয়)


[ ]পরিবর্তে ব্যবহার করে আপনি 2 বাইট সংরক্ষণ করতে পারেন (())
ckjbgames

@ckjbgames আপনি কি এটি সম্পর্কে নিশ্চিত !? Wich ব্যাশ সংস্করণ ব্যবহার করা হয়?
এফ। হাউরি

@ এফৌরি আমার ধারণা, বাইটের ক্ষেত্রে এটি একই রকম হবে।
ckjbgames

@ckjbgames আপনার সাথে [ ]ভেরিয়েবলের জন্য ডলার সাইন দরকার। আপনি কীভাবে একই বা ছোট দৈর্ঘ্যের সাহায্যে একই কাজ করতে পারবেন তা আমি দেখতে পাচ্ছি না [ ]
এফ। হাউরি

বোনাস টিপ: লুপের জন্য প্রথম লাইনটি যদি শুরু হয় ((...)), তবে কোনও নতুন লাইন বা স্থান প্রয়োজন হবে না। যেমন for((;10>n++;)){((n%3))&&echo $n;} অনলাইন চেষ্টা করে দেখুন!
প্রিমো

6

অসীম লুপগুলির জন্য একটি সংক্ষিপ্ত বাক্য গঠন (যা breakবা exitবিবৃতি দিয়ে পালাতে পারে ) is

for((;;)){ code;}

এটি while true;এবং এর চেয়ে কম while :;

আপনার যদি প্রয়োজন না হয় break( exitপালানোর একমাত্র উপায় হিসাবে), আপনি পরিবর্তে একটি পুনরাবৃত্ত ফাংশন ব্যবহার করতে পারেন।

f(){ code;f;};f

আপনার যদি বিরতি দরকার হয় তবে আপনার প্রস্থানের দরকার নেই এবং আপনাকে লুপের বাইরে কোনও পরিবর্তনশীল পরিবর্তন করার প্রয়োজন নেই, আপনি শরীরের চারপাশে বন্ধনীগুলির সাথে একটি পুনরাবৃত্ত ফাংশন ব্যবহার করতে পারেন যা ফাংশন বডিটি একটি সাবশেলে চালায়।

f()(code;f);f

6

এক-লাইন forলুপগুলি

একটি পরিসীমা বিস্তারের সাথে একত্রিত একটি গাণিতিক ভাবটি ব্যাপ্তির প্রতিটি আইটেমের জন্য মূল্যায়ন করা হবে। উদাহরণস্বরূপ নিম্নলিখিত:

: $[expression]{0..9}

expression10 বার মূল্যায়ন করবে ।

এটি প্রায়শই সমতুল্য forলুপের তুলনায় উল্লেখযোগ্যভাবে ছোট হয় :

for((;10>n++;expression with n)){ :;}
: $[expression with ++n]{0..9}

যদি আপনি কমান্ডটি ত্রুটিগুলি না পেয়ে মনে করেন তবে আপনি ইনিটেনালটি সরিয়ে ফেলতে পারেন :। 10 এর চেয়ে বড় পুনরাবৃত্তির জন্য, আপনি অক্ষর ব্যাপ্তিগুলিও ব্যবহার করতে পারেন, উদাহরণস্বরূপ {A..z}58 বার পুনরাবৃত্তি হবে।

ব্যবহারিক উদাহরণ হিসাবে, নিম্নলিখিত উভয়ই তাদের নিজস্ব লাইনে প্রথম 50 টি ত্রিভুজাকার সংখ্যা উত্পাদন করে:

for((;50>d++;)){ echo $[n+=d];} # 31 bytes
printf %d\\n $[n+=++d]{A..r}    # 28 bytes

আপনি for((;0<i--;)){ f;}
পিছনেও

5

আর্গুমেন্ট উপর লুপ

হিসাবে উল্লেখ করা একটি "foo বিন্যাস বারে ..." অংশ ছাড়া "জন্য" লুপ ব্যাশ , in "$@;"মধ্যে for x in "$@;"অপ্রয়োজনীয়।

থেকে help for:

for: for NAME [in WORDS ... ] ; do COMMANDS; done
    Execute commands for each member in a list.

    The `for' loop executes a sequence of commands for each member in a
    list of items.  If `in WORDS ...;' is not present, then `in "$@"' is
    assumed.  For each element in WORDS, NAME is set to that element, and
    the COMMANDS are executed.

    Exit Status:
    Returns the status of the last command executed.

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

for n;{ echo $[n*n];}

এটি অনলাইন চেষ্টা করুন!


5

বিড়ালের বিকল্প

বলুন আপনি কোনও ফাইল পড়ার চেষ্টা করছেন এবং এটি অন্য কোনও ক্ষেত্রে ব্যবহার করছেন। আপনি যা করতে পারেন তা হ'ল:

echo foo `cat bar`

তাহলে বিষয়বস্তু barছিল foobar, এই প্রিন্ট হবে foo foobar

তবে, আপনি যদি এই পদ্ধতিটি ব্যবহার করেন তবে একটি বিকল্প রয়েছে, যা 3 বাইট সংরক্ষণ করে:

echo foo `<bar`

1
<barনিজে থেকে কাজ না করে ব্যাকটিক্সে রেখে দেওয়ার কোনও কারণ আছে কি ?
ক্রিটসি লিথোস

পছন্দ করুন <কমান্ড করার জন্য একটি ফাইল রাখে, কিন্তু এই ক্ষেত্রে এটি একটি ছল কারণে মান আউটপুট মধ্যে এটা বন্ধ রাখে। ব্যাকটিকগুলি একসাথে এটি মূল্যায়ন করে।
Okx

স্ট্যান্ডার্ড ইনপুট ব্যতীত আর `cat`কি ছোট পড়ার উপায় আছে ?
জোয়েল

4

[পরিবর্তে [[এবং testযখন সম্ভব সম্ভব ব্যবহার করুন

উদাহরণ:

[ -n $x ]


তুলনার জন্য =পরিবর্তে ব্যবহার করুন==

উদাহরণ:

[ $x = y ]

নোট করুন যে আপনার অবশ্যই সমান চিহ্নের চারপাশে স্পেস থাকতে হবে অন্যথায় এটি কাজ করবে না। ==আমার পরীক্ষার উপর ভিত্তি করে একই প্রযোজ্য ।


3
[বনাম [[: যদি প্রয়োজনীয় কোট পরিমাণ উপর নির্ভর করে হতে পারে pastebin.com/UPAGWbDQ
manatwork

@ মান্যাটওয়ার্ক এটি একটি ভাল বিষয়।
nyuszika7h

1
সাধারণ নিয়ম: [... ]== /bin/test, তবে [[... ]]! = /bin/testএবং কাউকে পছন্দ করা উচিত নয় [... ]ওভার [[... ]]কোডগল্ফের বাইরে
বিড়াল

4

বিকল্প head

lineএর চেয়ে তিন বাইট কম head -1, তবে হ্রাস করা হচ্ছে ।

sed qদুই বাইট চেয়ে খাটো head -1

sed 9qএর চেয়ে এক বাইট ছোট head -9


1
যদিও ডুমড করা হয়েছে , আমরা এখনও একটি লাইন পড়তে ইউজার-লিনাক্স প্যাকেজ lineথেকে কিছু সময়ের জন্য ব্যবহার করতে পারি ।
manatwork

4

tr -cd এর চেয়ে কম grep -o

উদাহরণস্বরূপ, আপনার যদি স্পেসগুলি গণনা করতে হয়, grep -o <char>(কেবল মিলিত মুদ্রণ করুন) 10 বাইট দেয় যখন tr -cd <char>(পরিপূরক মুছুন <char>) 9 দেয়।

# 16 bytes
grep -o \ |wc -l
# 15 bytes
tr -cd \ |wc -c

( উত্স )

লক্ষ্য করুন যে তারা উভয়ই কিছুটা আলাদা আউটপুট দেয়। grep -oলাইন পৃথক ফলাফলগুলি tr -cdপ্রদান করে যখন সমস্ত একই লাইনে দেয়, তাই trসর্বদা অনুকূল নাও হতে পারে।


4

সংক্ষিপ্ত ফাইলের নাম

সাম্প্রতিক একটি চ্যালেঞ্জের মধ্যে আমি ফাইলটি পড়ার চেষ্টা করছিলাম /sys/class/power_supply/BAT1/capacity, তবে এই /*/*/*/*/capac*yবিন্যাসের সাথে অন্য কোনও ফাইল উপস্থিত না হওয়ায় এটি সংক্ষিপ্ত করা যেতে পারে ।

উদাহরণস্বরূপ, যদি আপনার কাছে foo/ফাইলগুলি সমন্বিত কোনও ডিরেক্টরি থাকে foo, bar, foobar, barfooএবং আপনি ফাইলটি উল্লেখ করতে চান তবে আপনি বাইট সংরক্ষণ foo/barfooকরতে ব্যবহার করতে পারেন foo/barf*

*"কোন" প্রতিনিধিত্ব করে আর Regex সমতূল্য .*


3

:কমান্ডের পরিবর্তে পাইপ ব্যবহার করুন /dev/null:বিল্ট-এ এটির সকল ইনপুট খাবে।


2
না, এটি বেশিরভাগ ক্ষেত্রে SIGPIPE সহ প্রোগ্রামটি ক্র্যাশ করবে। echo a|tee /dev/stderr|:কিছু মুদ্রণ করবে না।
জিমি 23013

একটি প্রতিযোগিতা রয়েছে: echo a|tee /dev/stderr|:আমার কম্পিউটারে একটি মুদ্রণ করেছিল, তবে অন্য কোথাও সাইনপাইপ সম্ভবত টি কে হত্যা করতে পারে। এটি সংস্করণের উপর নির্ভর করে tee
kernigh

হ্যাঁ, এটি একটি সিপাইপ সমস্যা: tee >(:) < <(seq 1 10)কাজ tee /dev/stderr | :করবে তবে তা করবে না। এমনকি a() { :;};tee /dev/stderr < <(seq 1 10)| aকিছু মুদ্রণ না।
এফ। হাউরি

@ ব্যবহারকারী ১40৪০২ - আপনার আমার পরিদর্শনে একটি ফ্রেসিং নাম থাকা উচিত ... যাইহোক, :অভ্যন্তরীণটি একেবারেই খায় না ... আপনি যদি কোলনের ইনপুটটি ধরে রাখেন তবে আপনি কোনও পাইপ বর্ধিত ত্রুটি থেকে বয়ে যেতে পারেন ... তবে আপনি পুনর্নির্দেশকে ভাসতে পারবেন কোনও কোলন দ্বারা, বা এটি দিয়ে একটি প্রক্রিয়া ফেলে দিন ... :| while i>&$(($??!$?:${#?})) command shit; do [ -s testitsoutput ]; doneবা তবে এটি ছদ্ম পরামর্শটি প্রযোজ্য ... এছাড়াও, আপনি কি জানেন যে আপনি আমার মতো প্রায় ভুতুড়ে? ... এ সব এড়ানো খরচ< <(psycho shit i can alias to crazy math eat your world; okay? anyway, ksh93 has a separate but equal composite char placement)
mikeserv

3

splitNপ্রতিটি লাইন বিভাগে ইনপুট বিভক্ত করার জন্য বাক্য গঠন রয়েছে: পরিবর্তে split -lNআপনি split -Nযেমন ব্যবহার করতে পারেন split -9


3

পরীক্ষাগুলি প্রসারিত করুন

মূলত, শেলটি এক ধরণের ম্যাক্রো ভাষা, বা কমপক্ষে একটি সংকর বা কোনও ধরণের is প্রতিটি কমান্ড-লাইন মূলত দুটি ভাগে বিভক্ত হতে পারে: পার্সিং / ইনপুট অংশ এবং সম্প্রসারণ / আউটপুট অংশ।

প্রথম অংশটি বেশিরভাগ লোকেরা কীসের দিকে মনোনিবেশ করেন কারণ এটি সর্বাধিক সহজ: আপনি কী পান তা আপনি দেখতে পান। দ্বিতীয় অংশটি হ'ল অনেকেই এমনকি খুব ভালভাবে বোঝার চেষ্টাও এড়িয়ে চলে এবং এ কারণেই লোকেরা evalখারাপ জিনিস বলে এবং সর্বদা আপনার বিস্তৃতি উদ্ধৃত করে - লোকেরা চায় প্রথম অংশের ফলাফলটি প্রথম অংশের সমান হয়। এটি ঠিক আছে - তবে এটি অহেতুক দীর্ঘ কোড শাখাগুলি এবং প্রচুর পরিমাণে বহিরাগত পরীক্ষার দিকে পরিচালিত করে।

বিস্তৃতি স্ব-পরীক্ষার${param[[:]#%+-=?]word}ফরম যথেষ্ট একটি প্যারামিটার বিষয়বস্তু যাচাই করতে চেয়ে বেশি হয়, nestable হয়, এবং সবার জন্য মূল্যায়ন প্রায় ভিত্তি করে NUL - যা কি অধিকাংশ লোক পরীক্ষার যাহাই হউক না কেন আশা। +লুপগুলিতে বিশেষত কার্যকর হতে পারে:

r()while IFS= read -r r&&"${r:+set}" -- "$@" "${r:=$*}";do :;done 2>&-

IFS=x
printf %s\\n some lines\ of input here '' some more|{ r;echo "$r"; }

somexlines ofxinputxhere

... readফাঁকা নয় লাইনগুলিতে "${r:+set}"টানাগুলি প্রসারিত হয় "set"এবং অবস্থানগুলি $rসংযুক্ত হয়ে যায়। কিন্তু যখন একটি ফাঁকা রেখা থাকে read, $rখালি থাকে এবং এতে "${r:+set}"প্রসারিত হয় ""- এটি একটি অবৈধ আদেশ। কিন্তু কারণ কম্যান্ড-লাইন সম্প্রসারিত করা হয় আগে"" নাল কমান্ড অনুসন্ধান করা হয়, "${r:=$*}"positionals প্রথম বাইট উপর ঘনিভূত সমস্ত মান লাগে $IFSহিসাবে ভাল। পরবর্তী ইনপুট অনুচ্ছেদটি পাওয়ার জন্য কমপাউন্ড কমান্ড ডাব্লু / r()আবার একটি আলাদা মান হিসাবে আবার কল করা যেতে পারে , যেহেতু ইনপুটটিতে পরবর্তী ইললাইন ছাড়িয়ে শেলের পক্ষে বাফার করা অবৈধ ।|{;}$IFSread\n


3

লুপগুলি সংক্ষিপ্ত করতে লেজ পুনরাবৃত্তি ব্যবহার করুন:

এগুলি আচরণের সমতুল্য (যদিও মেমরি / পিআইডি ব্যবহারে সম্ভবত এটি নয়):

while :;do body; done
f()(body;f);f
body;exec $0
body;$0

এবং এগুলি মোটামুটি সমতুল্য:

while condition; do body; done
f()(body;condition&&f);f
body;condition&&exec $0
body;condition&&$0

(প্রযুক্তিগতভাবে শেষ তিনটি সর্বদা সর্বদা অন্তত একবার শরীর চালিত করবে)

ব্যবহারের $0জন্য আপনার স্ক্রিপ্ট কোনও ফাইলের মধ্যে থাকা দরকার, ব্যাশ প্রম্পটে আটকানো হবে না।

শেষ পর্যন্ত আপনার স্ট্যাকটি উপচে পড়তে পারে তবে আপনি কিছু বাইট সংরক্ষণ করেন।


3

কখনও কখনও exprসাধারণের পরিবর্তে সাধারণ গাণিতিক অভিব্যক্তির ফলাফল প্রদর্শনের জন্য বিল্টিন ব্যবহার করা সংক্ষিপ্ত হয় echo $[ ]। উদাহরণ স্বরূপ:

expr $1 % 2

এর চেয়ে এক বাইট ছোট:

echo $[$1%2]

2

আউটপুট একটি লাইন উত্পন্ন করার pwdপরিবর্তে ব্যবহার করুনecho

স্ট্যাডআউটে একটি লাইন লাগানো দরকার তবে বিষয়বস্তুর যত্ন নেই এবং শেল বিল্টিনসে আপনার উত্তর সীমাবদ্ধ রাখতে চান? pwdচেয়ে বাইট খাটো echo


2

স্ট্রিং প্রিন্ট করার সময় উদ্ধৃতিগুলি বাদ দেওয়া যেতে পারে।

echo "example"
echo example

এসএম-টি 335 এলটিই, অ্যান্ড্রয়েড 5.1.1 এ আউটপুট:

u0_a177@milletlte:/ $ echo "example"
example
u0_a177@milletlte:/ $ echo example
example

2

অযৌক্তিক অ্যারে আইটেমগুলি বরাদ্দ করার সময়, আপনি এখনও ক্রমাগত খণ্ডগুলির ক্রমাগত সূচকগুলি এড়িয়ে যেতে পারেন:

bash-4.4$ a=([1]=1 [2]=2 [3]=3 [21]=1 [22]=2 [23]=3 [31]=1)

bash-4.4$ b=([1]=1 2 3 [21]=1 2 3 [31]=1)

ফলাফল একই:

bash-4.4$ declare -p a b
declare -a a=([1]="1" [2]="2" [3]="3" [21]="1" [22]="2" [23]="3" [31]="1")
declare -a b=([1]="1" [2]="2" [3]="3" [21]="1" [22]="2" [23]="3" [31]="1")

মতে man bash:

অ্যারেগুলি ফর্মের নাম = (মান 1 ... মান এন ) এর যৌগিক অ্যাসাইনমেন্ট ব্যবহার করার জন্য বরাদ্দ করা হয়েছে , যেখানে প্রতিটি মান ফর্মের [ সাবস্ক্রিপ্ট ] = স্ট্রিংয়ের । ইনডেক্সেড অ্যারে অ্যাসাইনমেন্টের জন্য স্ট্রিং ছাড়া কিছু প্রয়োজন হয় না । ইনডেক্সেড অ্যারেগুলিকে নির্ধারিত করার সময়, যদি alচ্ছিক বন্ধনী এবং সাবস্ক্রিপ্ট সরবরাহ করা হয় তবে সেই সূচকটি নির্ধারিত হয়; অন্যথায় নির্ধারিত উপাদানটির সূচক হ'ল শেষ সূচক যা বিবৃতিটি প্লাস ওয়ান দ্বারা নির্ধারিত হয়েছিল।


যোগ করতে সহায়ক: অবিচ্ছিন্ন উপাদানগুলি পাটিগণিতের বিস্তারে 0 এবং অন্য "" সম্প্রসারণে প্রসারিত হবে।
ডিজিটাল ট্রমা

2

প্রথম শব্দটি একটি স্ট্রিংয়ে মুদ্রণ করুন

যদি স্ট্রিংটি ভেরিয়েবলের মধ্যে aথাকে এবং এতে পলায়ন এবং বিন্যাসের অক্ষর ( \এবং %) না থাকে তবে এটি ব্যবহার করুন:

printf $a

ফলাফলটি মুদ্রণের পরিবর্তে পরিবর্তনশীলে সংরক্ষণের প্রয়োজন হলে এটি নিম্নলিখিত কোডের চেয়ে দীর্ঘতর হবে:

x=($a)
$x

1

1 টি forনির্দেশ দিয়ে 2 টি এম্বেড লুপ করছেন :

for ((l=i=0;l<=99;i=i>98?l++,0:++i)) ;do
    printf "I: %2d, L: %2d\n" $i $l
done |
    tee >(wc) | (head -n4;echo ...;tail -n 5)
I:  0, L:  0
I:  1, L:  0
I:  2, L:  0
I:  3, L:  0
...
I: 96, L: 99
I: 97, L: 99
I: 98, L: 99
I: 99, L: 99
  10000   40000  130000

1

উদ্ধৃত স্ট্রিং বরাদ্দ করুন এবং মুদ্রণ করুন

যদি আপনি কোনও ভেরিয়েবলের জন্য একটি উদ্ধৃত স্ট্রিং বরাদ্দ করতে চান এবং তারপরে সেই ভেরিয়েবলের মান মুদ্রণ করেন তবে তা করার স্বাভাবিক উপায় হ'ল:

a="Programming Puzzles & Code Golf";echo $a

যদি aপূর্বে সেট না করা থাকে তবে এটি সংক্ষিপ্ত করা যেতে পারে:

echo ${a=Programming Puzzles & Code Golf}

যদি aআগে সেট করা থাকে, তবে এটি পরিবর্তে ব্যবহার করা উচিত:

echo ${a+Programming Puzzles & Code Golf}

নোট করুন এটি শুধুমাত্র তখনই কার্যকর যখন স্ট্রিংয়ের উদ্ধৃতিগুলির প্রয়োজন (যেমন শ্বেত স্থান রয়েছে)। উদ্ধৃতি ছাড়া, a=123;echo $aঠিক যেমন সংক্ষিপ্ত।


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