বাশে নেস্টেড ব্রেস প্রসারণ রহস্য


19

এই:

$ echo {{a..c},{1..3}}

এটি উত্পাদন করে:

a b c 1 2 3

যা সুন্দর, তবে দেওয়া কঠিন বলে বোঝানো যায়

$ echo {a..c},{1..3}

দেয়

a,1 a,2 a,3 b,1 b,2 b,3 c,1 c,2 c,3

এটি কোথাও নথিভুক্ত করা হয়? ব্যাশ রেফারেন্স এটা উল্লেখ না (যদিও এটি এটি ব্যবহার একটি উদাহরণ আছে)।

উত্তর:


18

ঠিক আছে, এটি একবারে এক স্তর ছাড়াই:

X{{a..c},{1..3}}Y

এটিকে প্রসারিত হচ্ছে X{a..c}Y X{1..3}Y(যা সত্তা ও সত্তার সাথে X{A,B}Yপ্রসারিত ) হিসাবে নথিভুক্ত হয়, এগুলি প্রসারিত হচ্ছে বলে নথিভুক্ত হয় ।XA XBA{a..c}B{1..3}XaY XbY XcY X1Y X2Y X3Y

ডকুমেন্টিংয়ের পক্ষে মূল্যবান জিনিসগুলি হ'ল এগুলি বাসা বেঁধে দেওয়া যেতে পারে ( উদাহরণস্বরূপ প্রথমটি সেখানে প্রথমটি বন্ধ} করে না )।{

আমি মনে করি শেলগুলি প্রথমে অভ্যন্তরীণ ধনুর্বন্ধনীগুলি সমাধান করার জন্য বেছে নিতে পারত , প্রতিটি ঘুরেফিরে }পরিবর্তনের মাধ্যমে:

  1. X{{a..c},{1..3}}
  2. X{a,{1..3}}Y X{b,{1..3}}Y X{c,{1..3}}Y

    (যেমন A{a..c}Bপ্রসারিত AaB AbB AcB, যেখানে Aহয় X{এবং Bহয় ,{1..3}Y)

  3. X{a,1}Y X{a,2}Y X{a,3}Y X{b,1}Y X{b,2}Y X{b,3}Y X{c,1}Y X{c,2}Y X{c,3}Y

  4. XaY X1Y XaY Xa2...

তবে আমি এটি বিশেষত আরও স্বজ্ঞাত বা দরকারী বলে মনে করি না (উদাহরণস্বরূপ মন্তব্যে কেভিনের উদাহরণ দেখুন), বিস্তৃতিটি ক্রম সম্পাদনের ক্রমটি সম্পর্কে এখনও কিছুটা অস্পষ্টতা থাকতে পারে এবং এটি কীভাবে নয় csh(শেলটি ব্রাসের প্রবর্তন করেছিল 70 এর দশকের শেষের দিকে প্রসারণ, যখন {1..3}ফর্মটি পরে এসেছিল (1995) zshএবং {a..c}এখনও পরে (2004) থেকে bashএটি করেছে।

মনে রাখবেন csh(শুরু থেকে, 2BSD (1979) ম্যান পৃষ্ঠাটি দেখুন ) ব্রেস সম্প্রসারণ বাসা বাঁধতে পারে তা নথিবদ্ধ করেছিল, যদিও নেস্টেড ব্রেস সম্প্রসারণ কীভাবে প্রসারিত হবে তা স্পষ্টভাবে বলেননি। কিন্তু আপনি করতে পারেন তাকান csh1979 থেকে কোড দেখতে কিভাবে তাহলে করা হয়েছিল। দেখুন কীভাবে এটি প্রকৃতপক্ষে বাসা বাঁধে এবং কীভাবে এটি বাইরের ধনুর্বন্ধনী থেকে শুরু করে সমাধান করা হয়।

যাইহোক, আমি প্রসারণের কীভাবে {a..c},{1..3}কোনও প্রভাব ফেলতে পারে তা আমি সত্যিই দেখছি না । সেখানে, এটি ,কোনও বন্ধনী সম্প্রসারণের অপারেটর নয় (যেমন এটি ধনুর্বন্ধনীগুলির অভ্যন্তরে নেই), তাই কোনও সাধারণ চরিত্রের মতো আচরণ করা হয়।


আমার কাছে আশ্চর্য লাগে যে বাইরের ধনুর্বন্ধনীগুলি অভ্যন্তরীণগুলির আগে সমাধান হওয়ার কথা।
হউক লেগেছে

@ stéphane-chazelas দুটি স্পষ্ট উপায় আছে যে এই প্রকাশটি পার্স করা যেতে পারে। কেন এটি এক উপায়ে পার্স করা হয় অন্যভাবে নয়? আপনার মন্তব্যটি কোনও ব্যাখ্যা বলে মনে হচ্ছে না।
igal

সুতরাং, সেই ব্যাখ্যাটি বোধগম্য হয়, তবে এটি যদি "প্রসারিত হচ্ছে তাই নথিভুক্ত করা হয় ..." তবে কোনও URL আছে কি?
xenoid

@ এক্সেনয়েড আমার আপডেট সমাধান দেখুন।
igal

1
@ (প্রত্যেকে): সম্প্রসারণ বিবেচনা করুন /dev/{h,s}d{a..d}{1..4,}। এখন আপনি প্রসারিত করতে এটি অন্তর্ভুক্ত করতে চান অনুমান করা /dev/nullএবং /dev/zero। যদি ব্রেস প্রসারণটি ভিতর থেকে কাজ করে, তবে সেই সম্প্রসারণটি নির্মাণে সত্যই বিরক্তিকর হবে। তবে এটি বাইরে থেকে কাজ করে বলে, এটি বেশ তুচ্ছ:/dev/{null,zero,{h,s}d{a..d}{1..4,}}
কেভিন

7

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

আপনি যা হারিয়েছিলেন তা হ'ল বন্ধনী-বিস্তৃতি কীভাবে সম্পাদিত হয় তার সংজ্ঞা। এখানে তিনটি উল্লেখ রয়েছে:

আরও একটি বিশদ বিবরণ নিম্নলিখিত।


আপনি এই অভিব্যক্তির ফলাফলের সাথে তুলনা করেছেন:

$ echo {{a..c},{1..3}}
a b c 1 2 3

এই মত প্রকাশের ফলাফল:

$ echo {a..c},{1..3}
a,1 a,2 a,3 b,1 b,2 b,3 c,1 c,2 c,3

আপনি বলেছেন যে এটি ব্যাখ্যা করা শক্ত, অর্থাত্ এটি পাল্টা স্বজ্ঞাত। কী অনুপস্থিত তা হ'ল বন্ধনী-বিস্তৃতি কীভাবে প্রক্রিয়া করা হয় তার একটি আনুষ্ঠানিক সংজ্ঞা। আপনি নোট করেছেন যে বাশ ম্যানুয়াল পুরো সংজ্ঞা দেয় না।

আমি কিছুটা অনুসন্ধান করেছি কিন্তু আমি অনুপস্থিত (সম্পূর্ণ, আনুষ্ঠানিক) সংজ্ঞাটিও পাই না। সুতরাং আমি উত্স কোড গিয়েছিলাম:

উত্সটিতে বেশ কয়েকটি দরকারী মন্তব্য রয়েছে। প্রথমটি হ'ল বন্ধনী সম্প্রসারণ অ্যালগরিদমের একটি উচ্চ-স্তরের ওভারভিউ:

Basic idea:

Segregate the text into 3 sections: preamble (stuff before an open brace),
postamble (stuff after the matching close brace) and amble (stuff after
preamble, and before postamble).  Expand amble, and then tack on the
expansions to preamble.  Expand postamble, and tack on the expansions to
the result so far.

সুতরাং একটি ধনুর্বন্ধনী-প্রসারণ টোকেনের বিন্যাসটি নিম্নলিখিত:

<PREAMBLE><AMBLE><POSTAMBLE>

মূল প্রসারণের মূল প্রবেশ-পয়েন্টটি একটি ফাংশন বলা হয় brace_expandযা নীচে বর্ণিত:

Return an array of strings; the brace expansion of TEXT.

সুতরাং brace_expandফাংশনটি একটি ব্রেস প্রসারিত এক্সপ্রেশনকে উপস্থাপন করে একটি স্ট্রিং নেয় এবং প্রসারিত স্ট্রিংগুলির অ্যারে প্রদান করে।

এই দুটি পর্যবেক্ষণের সংমিশ্রণে আমরা দেখতে পাচ্ছি am পোস্টমাম্বলটিকে তারপরে স্ট্রিংয়ের তালিকায় প্রসারিত করা হয় এবং পোস্টাম্বল তালিকার প্রতিটি স্ট্রিং উপস্থাপনযোগ্য / এম্বেল তালিকার প্রতিটি স্ট্রিংয়ের সাথে সংযুক্ত করা হয় (অর্থাত্ দুটি তালিকার পণ্য গঠিত হয়)। তবে এটি কীভাবে সামঞ্জস্যপূর্ণ এবং পোস্টাম্বল প্রক্রিয়াজাত করা হয় তা বর্ণনা করে না। ভাগ্যক্রমে সেই সাথে বর্ণনা করার জন্য একটি মন্তব্য রয়েছে। এম্বেলটি এমন একটি ফাংশন দ্বারা প্রক্রিয়াজাত হয় expand_ambleযার নাম সংজ্ঞায়িত করা হয় নিম্নলিখিত মন্তব্যের আগে:

Expand the text found inside of braces.  We simply try to split the
text at BRACE_ARG_SEPARATORs into separate strings.  We then brace
expand each slot which needs it, until there are no more slots which
need it.

কোডের অন্য কোথাও আমরা দেখতে পাচ্ছি যে BRACE_ARG_SEPARATOR কমা হিসাবে সংজ্ঞায়িত হয়েছে। এটি স্পষ্ট করে দেয় যে অ্যাম্বলটি একটি কমা-বিচ্ছিন্ন স্ট্রিংয়ের তালিকা, যার মধ্যে কয়েকটি ব্রেস-এক্সপেনশন এক্সপ্রেশনও হতে পারে। এই স্ট্রিংগুলি পরে একটি একক অ্যারে গঠন করে। পরিশেষে, আমরা তাও দেখতে পারেন যে পরে expand_ambleবলা হয় brace_expandফাংশন তারপর postamble উপর যাও recursively বলা হয়। এটি আমাদেরকে অ্যালগরিদমের সম্পূর্ণ বিবরণ দেয়।

কিছু অন্যান্য (বেসরকারী) রেফারেন্স রয়েছে যা এই অনুসন্ধানকে সমর্থন করে।

একটি রেফারেন্সের জন্য, ব্যাশ হ্যাকারস উইকি পরীক্ষা করে দেখুন । সংমিশ্রণ এবং নেস্টিংয়ের বিভাগটি আপনার সমস্যাটিকে পুরোপুরি সমাধান করে না, তবে পৃষ্ঠাটি ব্রেস প্রসারণের বাক্য গঠন / ব্যাকরণ দেয়, যা আমি মনে করি আপনার প্রশ্নের উত্তর দেয়। বাক্য গঠনটি নিম্নলিখিত নিদর্শনগুলি দ্বারা দেওয়া হয়:

{string1,string2,...,stringN}

{<START>..<END>}

<PREAMBLE>{........}

{........}<POSTSCRIPT>

<PREAMBLE>{........}<POSTSCRIPT>

এবং পার্সিংটি নিম্নরূপ বর্ণিত হয়েছে:

ব্রেস এক্সপেনশন স্বেচ্ছাসেবী স্ট্রিং উত্পন্ন করতে ব্যবহৃত হয়। নির্দিষ্ট স্ট্রিংগুলি surroundingচ্ছিক পার্শ্ববর্তী উপস্থাপত্র এবং পোস্ট স্ক্রিপ্টগুলির সাথে সমস্ত সম্ভাব্য সংমিশ্রণ তৈরি করতে ব্যবহৃত হয় ।

অন্য একটি রেফারেন্সের জন্য, ব্যাশ বিগিনিয়ার গাইডটি দেখুন , যা এখানে নীচে বলে:

Brace expansion is a mechanism by which arbitrary strings may be generated. Patterns to be brace-expanded take the form of an optional PREAMBLE, followed by a series of comma-separated strings between a pair of braces, followed by an optional POSTSCRIPT. The preamble is prefixed to each string contained within the braces, and the postscript is then appended to each resulting string, expanding left to right.

সুতরাং ব্রেস-এক্সপেনশন এক্সপ্রেশনগুলি বিশ্লেষণ করতে আমরা বাম থেকে ডানে চলে যাই, প্রতিটি অভিব্যক্তি প্রসারিত করে এবং ধারাবাহিক পণ্যগুলি তৈরি করি (স্ট্রিং-কনটেনটেশনের ক্রিয়াকলাপের ক্ষেত্রে)।

এখন আসুন আপনার প্রথম অভিব্যক্তি বিবেচনা করুন:

{{a..c},{1..3}}

বাশ হ্যাকারের উইকের ভাষায়, এটি প্রথম ফর্মটির সাথে মেলে:

{string1,string2,...,stringN}

কোথায় N=2, string1={a..c}এবং string2={1..3}- ভিতরে বক্রবন্ধনী প্রসারণও প্রথম সম্পাদনা করা হচ্ছে এবং তাদের প্রতিটি ফর্মের হচ্ছে {<START>..<END>}। বিকল্পভাবে, আমরা বলতে পারি যে এটি একটি ধনুর্বন্ধনী-সম্প্রসারণ অভিব্যক্তি যা কেবলমাত্র একটি ছাঁটাই (কোনও উপস্থাপনা বা পোস্টমামেবল) নিয়ে গঠিত। এম্বেলটি কমা দ্বারা বিযুক্ত তালিকা, সুতরাং আমরা তালিকাটিতে একবারে একটি স্লট দিয়ে যাই, এবং যেখানে প্রয়োজন সেখানে অতিরিক্ত বিস্তৃতিও সম্পাদন করি। কোনও পণ্য তৈরি হয় না কারণ এখানে কোনও সংলগ্ন অভিব্যক্তি নেই (কমাটি বিভাজক হিসাবে ব্যবহৃত হয়)।

পরবর্তী আপনার দ্বিতীয় অভিব্যক্তি তাকান:

{a..c},{1..3}

বাশ হ্যাকারের উইকের ভাষায়, এই অভিব্যক্তিটি ফর্মটির সাথে মেলে:

{........}<POSTSCRIPT>

যেখানে পোস্টস্ক্রিপ্ট হল সাব-এক্সপ্রেশন ,{1..3}। বিকল্পভাবে, আমরা বলতে পারি যে এই অভিব্যক্তিটির একটি সামঞ্জস্যপূর্ণ ( {a..c}) এবং একটি পোস্টাম্বল ( ,{1..3}) রয়েছে। কাঠামোটি তালিকায় প্রসারিত হয় a b cএবং তারপরে পোস্টমামিলের প্রসারণের প্রতিটি স্ট্রিংয়ের সাথে এগুলির প্রতিটি সংযুক্ত করা হয়। পোস্টমামলটি পুনরাবৃত্তিমূলকভাবে প্রক্রিয়াজাত করা হয়: এটির একটি উপস্থাপনা ,এবং এর একটি প্রতীক রয়েছে {1..3}। এটি তালিকায় প্রসারিত ,1 ,2 ,3। দুটি তালিকা a b cএবং ,1 ,2 ,3তারপরে একত্রিত হয়ে পণ্য তালিকা তৈরি করা হয় a,1 a,2 a,3 b,1 b,2 b,3 c,1 c,2 c,3

এই এক্সপ্রেশনগুলি কীভাবে পার্স করা হয়েছে তার একটি চিত্রযুক্ত-বীজগণিত বিবরণ দিতে সাহায্য করতে পারে, যেখানে বন্ধনী "[]" অ্যারেগুলি বোঝায়, "+" অ্যারে কনটেনটেশনকে বোঝায়, এবং "*" কার্টেসিয়ান পণ্যটিকে বোঝায় (সংক্ষেপে শ্রদ্ধার সাথে)।

এখানে প্রথম প্রকাশটি কীভাবে প্রসারিত হবে (প্রতি লাইনে এক ধাপ):

{{a..c},{1..3}}
{a..c} + {1..3}
[a b c] + [1 2 3]
a b c 1 2 3

এবং এখানে দ্বিতীয় প্রকাশটি কীভাবে প্রসারিত হবে:

{a..c},{1..3}
{a..c} * ,{1..3}
[a b c] * [,1 ,2 ,3]
a,1 a,2 a,3 b,1 b,2 b,3 c,1 c,2 c,3

2

আমার বোঝার বিষয়টি হ'ল:

অভ্যন্তরীণ ধনুর্বন্ধনীগুলি প্রথমে সমাধান করা হয় (সর্বদা হিসাবে) যা ঘুরিয়ে দেয়

{{a..c},{1..3}}

মধ্যে

{a,b,c,1,2,3}

কারণ এটি ,বন্ধনীগুলির মধ্যে রয়েছে এটি কেবল বন্ধনী উপাদানগুলিকে পৃথক করে।

তবে এর ক্ষেত্রে

{a..c},{1..3}

,ধনুর্বন্ধনী অর্থাৎ মধ্যেই উভয় পক্ষের বক্রবন্ধনী একাধিক বিন্যাসন ঘটাচ্ছে একজন সাধারণ চরিত্র নয়।


তাই {a..c}হয় সমাধান করা a,b,cবা a b cআর্দ্রতা এবং ডাউ জোনের উপর নির্ভর করে? ঝরঝরে।
kubanczyk

এটি কিছুটা বিভ্রান্তিকর বলে মনে হচ্ছে। যদি {{a..c},{1..3}}একইরকম হয় {a,b,c,1,2,3}তবে কি {{a..c}.{1..3}}একইরকম হওয়া উচিত নয় {a,b,c.1,2,3}? এটি অবশ্যই ঘটনা নয়।
ilkkachu

@ ইলক্কাচু কেন এমন হওয়া উচিত? ,বন্ধনী সম্প্রসারণ বিচ্ছেদ চরিত্র, .হয় না। কেন একটি সাধারণ চরিত্র একটি বিশেষ চিত্রের মতো একই ফলাফলের দিকে পরিচালিত করে? c.1একটি ধনুর্বন্ধনী উপাদান। কিন্তু এ বাম এবং ডান দিকে বক্রবন্ধনী প্রসারণও জন্য ভিত্তিভূমি। বাইরের ধনুর্বন্ধনী সঙ্গে ব্রেস সম্প্রসারণের জন্য ব্যবহৃত হয় কারণ তাদের সামগ্রীতে ব্রেস সম্প্রসারণ ফর্ম্যাট রয়েছে কারণ সেগুলি নয় কারণ তাদের সামগ্রীতে সেই বিন্যাস নেই। {a..c}.{1..3}.,.
Hauke ​​Lage

@HaukeLaging, ভাল, যদি {{a..c},{1..3}}মধ্যে সক্রিয় {a,b,c,1,2,3}তারপর কিছু কমা ঠিক মধ্যে হাজির a, bএবং c। তারা কেন একইভাবে উপস্থিত হবে না {a..c}.{1..3}? @Kubanczyk মন্তব্যটি একই জিনিস সম্পর্কে, যদি কমাগুলি সেখানে উপস্থিত হয় তবে সম্প্রসারণ কমাটি কখন তৈরি করে এবং কখন তা ঘটে না তা আমরা কীভাবে জানব? অবশ্যই উত্তরটি হ'ল এটি কখনই নিজের দ্বারা কোনও কমা তৈরি করে না, এটি শব্দের একটি তালিকা তৈরি করে। সুতরাং কিছুই {a,b,c,1,2,3}বা পরিণত হয় না {a,b,c.1,2,3}
ilkkachu

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