"বিপরীত ক্রম" তে বন্ধনী প্রসারণ প্রয়োগ করুন


21

উদাহরণস্বরূপ {a..c}{1..3}প্রসারিত হয় a1 a2 a3 b1 b2 b3 c1 c2 c3

আমি যদি মুদ্রণ করতে চাইতাম a1 b1 c1 a2 b2 c2 a3 b3 c3, তা করার মতো কোনও উপায় আছে কি? সবচেয়ে সহজ উপায় কি?

উত্তর:



10

এই বিশেষ ক্ষেত্রে, আমি মনে করি যে স্টাফেন চেজেলাস প্রদত্ত বিকল্পটি সর্বোত্তম।

অন্যদিকে, আপনি যখন আরও জটিল জিনিসগুলি প্রসারিত করেন, এই বিকল্পটি ভালভাবে স্কেল হয় না। সুতরাং, আপনি এটি দিয়ে এটি অর্জন করতে পারেন:

$ printf '%s\0' {a..c}{1..3} | sort -zk 1.2,1.2 | tr '\0' ' '

যা প্রত্যাবর্তন করে:

a1 b1 c1 a2 b2 c2 a3 b3 c3

কিছুটা অগোছালো মনে হচ্ছে, তবে এখন, ক্রমটিতে আমার একটি বিশাল নিয়ন্ত্রণ রয়েছে, কেবল উপরের কমান্ডটিতে দুটি অক্ষর পরিবর্তন করা হয়েছে; উদাহরণ স্বরূপ:

$ echo {a..b}{1..2}{a..b}{1..2}

এটি প্রসারিত হবে:

a1a1 a1a2 a1b1 a1b2 a2a1 a2a2 a2b1 a2b2 b1a1 b1a2 b1b1 b1b2 b2a1 b2a2 b2b1 b2b2

ধরুন আমি 1দ্বিতীয় প্রসারণে সমস্ত চাই , তারপরে 2:

$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.2,1.2 | tr '\0' ' '
a1a1 a1a2 a1b1 a1b2 b1a1 b1a2 b1b1 b1b2 a2a1 a2a2 a2b1 a2b2 b2a1 b2a2 b2b1 b2b2

ধরুন আমি aতৃতীয় প্রসারণের সমস্ত চাই , তারপরে b:

$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.3,1.3 | tr '\0' ' '
a1a1 a1a2 a2a1 a2a2 b1a1 b1a2 b2a1 b2a2 a1b1 a1b2 a2b1 a2b2 b1b1 b1b2 b2b1 b2b2

ধরুন আমি 1চতুর্থ সম্প্রসারণে সমস্ত চাই , তারপরে 2:

$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.4,1.4 | tr '\0' ' '
a1a1 a1b1 a2a1 a2b1 b1a1 b1b1 b2a1 b2b1 a1a2 a1b2 a2a2 a2b2 b1a2 b1b2 b2a2 b2b2

মনে করুন আমি 1aমাঝখানে সমস্ত চাই , তারপরে 1b, তারপরে 2a, তারপরে 2b:

$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -zk 1.2,1.3 | tr '\0' ' '
a1a1 a1a2 b1a1 b1a2 a1b1 a1b2 b1b1 b1b2 a2a1 a2a2 b2a1 b2a2 a2b1 a2b2 b2b1 b2b2

আপনি এমনকি rপূর্বের কমান্ডটিতে কেবলমাত্র একটি যুক্ত করে উপরের বিস্তৃতিতে ঠিক তত সহজেই কোনও বিপরীতকে বিপরীত করতে পারেন ; উদাহরণস্বরূপ, শেষটি:

$ printf '%s\0' {a..b}{1..2}{a..b}{1..2} | sort -rzk 1.2,1.3 | tr '\0' ' '
b2b2 b2b1 a2b2 a2b1 b2a2 b2a1 a2a2 a2a1 b1b2 b1b1 a1b2 a1b1 b1a2 b1a1 a1a2 a1a1

দ্রষ্টব্য : সাধারণত, যদি এই চূড়ান্ত সম্প্রসারণটি যুক্তিগুলির তালিকা হিসাবে ব্যবহার করা হয়, তবে পিছনের স্থানটি কোনও সমস্যা নয়; তবে আপনি যদি এ থেকে মুক্তি পেতে চান তবে উপরের যে কোনও কমান্ডের সাথে আপনি যুক্ত করতে পারেন, উদাহরণস্বরূপ| sed 's/ $//' ; বা এমনকি| sed 's/ $/\n/', এটির জন্য চলমান স্থানটি পরিবর্তন করতেnewline

নোট ২ : উপরের উদাহরণগুলিতে, আমিধারণার প্রমাণের জন্য সরলতার জন্যদুটি উপাদানগুলির (যেমন: {a, b} এবং {1,2} ) উপগ্রহগুলি ব্যবহার করেছি: আপনি যে কোনও সীমাবদ্ধ দৈর্ঘ্যের সাবসেট ব্যবহার করতে পারেন এবং সংশ্লিষ্ট কমান্ড, তুলনাযোগ্য হবে।


5

bash, ksh, zsh

(ব্যাশ, ksh, zsh) কাজ করে এমন একটি লাইনার (সমস্ত শেল বিপরীত ক্রমে "ব্রেস প্রসারণ" করতে পারে না):

$ echo {3..1}{c..a} | rev
a1 b1 c1 a2 b2 c2 a3 b3 c3

একটি বিকল্প যা ব্যবহার করে eval(যা এখনও ব্যাশ, কেএসএস, জেডএস এবং আরও ক্রিপ্টিক হতে পারে):

$ eval echo '{a..c}'{1..3}
a1 b1 c1 a2 b2 c2 a3 b3 c3

বোঝার জন্য সেখানে কি ঘটছে, প্রতিস্থাপন evalসঙ্গে echo:

$ echo echo '{a..c}'{1..3}
echo {a..c}1 {a..c}2 {a..c}3

কমান্ড মৃত্যুদন্ড কার্যকর (Eval সম্প্রসারণ পরে) আসলে echo {a..c}1 {a..c}2 {a..c}3। যা আপনি চান / প্রয়োজন হিসাবে প্রসারিত হয়।

সমস্ত শাঁস

"ব্রেস বিস্তৃতি" ছাড়াই বেশ কয়েকটি শেল রয়েছে, সুতরাং, "সমস্ত শেল" এর জন্য এটি ব্যবহার করা সম্ভব নয়। আমাদের একটি লুপ প্রয়োজন (একটি পিছনে সাদা স্থান সহ):

$ for i in 1 2 3; do for j in a b c; do printf "%s%s " "$j" "$i"; done; done; echo
a1 b1 c1 a2 b2 c2 a3 b3 c3 

আপনার যদি অবশ্যই কোনও চলার জায়গা না থাকে:

s=""
for i in 1 2 3; do
    for j in a b c; do
        printf "%s%s%s" "$s" "$j" "$i"
        s=" "
    done
done
echo

ছাপে

a1 b1 c1 a2 b2 c2 a3 b3 c3

যদি আপনাকে অনেক মানগুলির জন্য এটি করতে হয় তবে সংখ্যার একটি তালিকা তৈরি করতে আমাদের ব্রেস সম্প্রসারণের অনুরূপ কিছু ব্যবহার করতে হবে $(seq 10)। এবং, যেমন সেক অক্ষরগুলির একটি তালিকা তৈরি করতে পারে না, তাই আমাদের উত্পন্ন সংখ্যাগুলি ascii রূপান্তর করতে হবে:

s=""
for i in $(seq 4); do
    for j in $(seq 5); do
        printf "%s\\$(printf %03o $((96+j)))%s" "$s" "$i"
        s=" "
    done
done
echo

কপি করে প্রিন্ট:

a1 b1 c1 d1 e1 a2 b2 c2 d2 e2 a3 b3 c3 d3 e3 a4 b4 c4 d4 e4

আপনি yash -o braceexpandতালিকায় যুক্ত করতে পারেন ।
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস আমার নিশ্চিত নয় যে আমার উচিত। কমান্ডটি লিনাক্সে yash -o braceexpand -c 'echo {3..1}{c..a}'মুদ্রণ 3{c..a} 2{c..a} 1{c..a}করে। পুরো "ব্রেস এক্সপেনশন" নয়।
ইসহাক

3
{a..c}1 {a..c}2 {a..c}3

ব্রেস {a..c}{1..3}প্রসারিতগুলি বাম থেকে ডানে প্রসারিত হয়, সুতরাং আপনি প্রথমে পাবেন a{1..3} b{1..3} c{1..3}এবং তারপরে বর্ণগুলি সংখ্যার সাথে একত্রিত হবে a1 a2 a3 b1 b2 b3 c1 c2 c3। আপনি যে অর্ডারটি চান তা পেতে, আপনাকে উপরের কিছুটা দীর্ঘতর এক্সপ্রেশন ব্যবহার করতে হবে।


আপনি যদি এটি "সংখ্যার" বিশাল পরিসরের জন্য করতে চান তবে এটি আর ব্যবহারিক হবে না।
রাবেন গোনালো মুরোও 21

3
@ RUBENGONÇALOMOROUÇO না এটি হবেনা এবং আপনি যদি এটি প্রচুর সংখ্যার জন্য করছেন তবে আমি ডাবল লুপের মতো বিকল্প পদ্ধতি ব্যবহার করার পরামর্শ দেব। এটি হাজার হাজার সংমিশ্রণের জন্য কাজ করবে, যেখানে একটি প্রবন্ধে কিছু নির্দিষ্ট প্রসঙ্গে আমার ট্রিগার "যুক্তি তালিকা খুব দীর্ঘ" বিস্তৃত হয়।
কুসালানন্দ

2

একটি লুপ ব্যবহার:

for n in {1..3}; do printf '%s\n' {a..c}"$n"; done

এটি আপনার প্রথম সম্প্রসারণের মধ্য দিয়ে লুপ করবে এবং তারপরে দ্বিতীয়টির সাথে প্রতিটি অক্ষর প্রসারিত করবে।

আপনার যদি এক লাইনে আউটপুট প্রয়োজন হয় তবে আপনি এগুলি সরাতে পারেন \n:

for n in {1..3}; do printf '%s ' {a..c}"$n"; done

এটি আপনাকে ট্রেলিং করা নতুন লাইন দেয় না তবে আপনি যদি এটি কোনও আদেশ বা ভেরিয়েবলের কাছে পৌঁছে দিচ্ছেন তবে এটি কোনও সমস্যা নয়।


1
লুপ সমাধানের জন্য এতগুলি ডাউন ভোট কেন?
ইসহাক

দুহ আমি অবশ্যই ভুল প্রশ্ন পড়েছি। আপডেট হয়েছে
জেসি_বি

2

এটি আপনার সাধারণ ক্ষেত্রে কাজ করে এবং এটি বাড়ানো যেতে পারে তবে এটি দ্রুত হাতছাড়া হয়ে যায়। আরও জটিল কেসগুলির জন্য এটি কাজ করে না এটি নির্মাণ করা সহজ।

বন্ধনী বিস্তারের ক্রমটি বিপরীত করুন, তারপরে অক্ষরগুলি অদলবদল করুন:

echo {1..3}{a..c} | sed -E 's/(.)(.)( ?)/\2\1\3/g'

@ মুরু: উফ! সংশোধন করা হয়েছে। ধন্যবাদ।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।


0

একটি সহজ পদ্ধতিটি বাছাই করতে হবে (১.২,১.২ এর অর্থ হল যে আপনি একটি অক্ষরকে দ্বিতীয় অবস্থানে নিয়ে যান এবং একই জায়গায় শেষ করবেন)।

$ for i in {a..c}{1..3}; do echo $i; done|sort -n -k1.2,1.2
a1
b1
c1
a2
b2
c2
a3
b3
c3

আপনি যদি এগুলিকে এক লাইনে চান তবে আপনি ট্র এর মতো ব্যবহার করতে পারেন:

$ for i in {a..c}{1..3}; do echo $i; done|sort -n -k1.2,1.2|tr '\n' ' '
a1 b1 c1 a2 b2 c2 a3 b3 c3

-2

নীচের পদ্ধতি দ্বারা সম্পন্ন

for i in {1..10}; do for j in {a..c}; do echo $j$i; done; done| perl -pne "s/\n/ /g"

আউটপুট

a1 b1 c1 a2 b2 c2 a3 b3 c3 a4 b4 c4 a5 b5 c5 a6 b6 c6 a7 b7 c7 a8 b8 c8 a9 b9 c9 a10 b10 c10

এছাড়াও বিবেচনা করুনfor i in {1..10}; do for j in {a..c}; do printf '%s ' "$j$i"; done; done;echo
জেফ শ্যাচলার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.