আমি কীভাবে এটি করতে পারি echo
?
perl -E 'say "=" x 100'
ruby -e 'puts "=" * 100'
বাpython -c 'print "=" * 100'
printf
সঙ্গে seq
)svrb=`printf '%.sv' $(seq $vrb)`
আমি কীভাবে এটি করতে পারি echo
?
perl -E 'say "=" x 100'
ruby -e 'puts "=" * 100'
বাpython -c 'print "=" * 100'
printf
সঙ্গে seq
)svrb=`printf '%.sv' $(seq $vrb)`
উত্তর:
তুমি ব্যবহার করতে পার:
printf '=%.0s' {1..100}
এটি কীভাবে কাজ করে:
বাশ {1..100} প্রসারিত করে যাতে কমান্ডটি হয়ে যায়:
printf '=%.0s' 1 2 3 4 ... 100
আমি প্রিন্টফের বিন্যাসটি সেট করে রেখেছি =%.0s
যার অর্থ এটি যে =
কোনও যুক্তিই দেওয়া হোক না কেন এটি সর্বদা একটি মুদ্রণ করবে । অতএব এটি 100 =
টি মুদ্রণ করে ।
repl = 100
উদাহরণস্বরূপ, এখানে একটি ফাংশন র্যাপারটি দিয়ে আপনি অনুরোধ করতে পারেন ( eval
কৌতূহলটি প্রয়োজন, দুর্ভাগ্যবশত, একটি চলকের উপর ব্রেস প্রসারিত করার জন্য):repl() { printf "$1"'%.s' $(eval "echo {1.."$(($2))"}"); }
seq
পরিবর্তে যেমন ব্যবহার করুন $(seq 1 $limit)
।
$s%.0s
থেকে %.0s$s
অন্যথায় ড্যাশ একটি কারণ printf
ত্রুটি।
printf
: কোনও তর্ক বাকী না হওয়া পর্যন্ত এটি ফর্ম্যাট স্ট্রিংটি প্রয়োগ করে চলেছে। আমি ধরে নিয়েছি এটি কেবল একবার বিন্যাস স্ট্রিং প্রক্রিয়াজাত!
কোন সহজ উপায়। তবে উদাহরণস্বরূপ:
seq -s= 100|tr -d '[:digit:]'
অথবা হতে পারে একটি মানসম্পন্ন উপায়:
printf %100s |tr " " "="
এখানে একটা ব্যাপার tput rep
, কিন্তু হাত থেকে আমার টার্মিনাল (xterm এবং Linux) এর জন্য তারা এটা সমর্থন বলে মনে হচ্ছে না :)
=
অক্ষর মুদ্রণ করবে ।
printf
tr
একমাত্র পসিক্স সমাধান কারণ seq
, yes
এবং {1..3}
পসিক্স নয়।
printf %100s | sed 's/ /abc/g'
- 'অ্যাবাক্যাব্যাক্যাবি ...'
tr
)। আপনি এটির মতো কিছুতেও প্রসারিত করতে পারেন printf "%${COLUMNS}s\n" | tr " " "="
।
wc
। এটি থেকে কেবলমাত্র উপসংহারটিই আমি নিতে পারি " seq
এটি ব্যবহার করা উচিত নয়"।
তার ইনপুটটির জন্য @ gniourf_gniourf এ টুপিটির টিপ ।
দ্রষ্টব্য: এই উত্তরটি মূল প্রশ্নের উত্তর দেয় না , তবে পারফরম্যান্সের সাথে তুলনা করে বিদ্যমান, সহায়ক উত্তরগুলির পরিপূরক করে ।
সমাধানগুলি কেবল কার্যকর করার গতির ক্ষেত্রে তুলনা করা হয় - মেমরির প্রয়োজনীয়তাগুলি বিবেচনায় নেওয়া হয় না (এগুলি সমাধানের ক্ষেত্রে পৃথক হয়ে যায় এবং বৃহত পুনরাবৃত্তি গণনাগুলির সাথে গুরুত্বপূর্ণ হতে পারে)।
সারসংক্ষেপ:
${var// /=}
) দিয়ে এড়িয়ে চলুন , কারণ এটি নিষিদ্ধভাবে ধীর।ওএসএক্স 10.10.4 এবং ব্যাশ 3.2.57 চলমান, 3.2 গিগাহার্টজ ইন্টেল কোর আই 5 সিপিইউ এবং একটি ফিউশন ড্রাইভ সহ 2012-এর শেষের দিকে আইম্যাকটিতে নিম্নলিখিত সময়গুলি নেওয়া হয়েছে এবং এটি 1000 রানের গড়।
এন্ট্রিগুলি হ'ল:
M
... একটি সম্ভাব্য মাল্টি- চর্যাক্টর সমাধানS
... একটি একক -চরিত্র-কেবল সমাধানP
... একটি পসিক্স-সম্মতিযুক্ত সমাধান[M, P] printf %.s= [dogbane]: 0.0002
[M ] printf + bash global substr. replacement [Tim]: 0.0005
[M ] echo -n - brace expansion loop [eugene y]: 0.0007
[M ] echo -n - arithmetic loop [Eliah Kagan]: 0.0013
[M ] seq -f [Sam Salisbury]: 0.0016
[M ] jot -b [Stefan Ludwig]: 0.0016
[M ] awk - $(count+1)="=" [Steven Penny (variant)]: 0.0019
[M, P] awk - while loop [Steven Penny]: 0.0019
[S ] printf + tr [user332325]: 0.0021
[S ] head + tr [eugene y]: 0.0021
[S, P] dd + tr [mklement0]: 0.0021
[M ] printf + sed [user332325 (comment)]: 0.0021
[M ] mawk - $(count+1)="=" [Steven Penny (variant)]: 0.0025
[M, P] mawk - while loop [Steven Penny]: 0.0026
[M ] gawk - $(count+1)="=" [Steven Penny (variant)]: 0.0028
[M, P] gawk - while loop [Steven Penny]: 0.0028
[M ] yes + head + tr [Digital Trauma]: 0.0029
[M ] Perl [sid_com]: 0.0059
awk
এবং perl
সমাধানগুলি এড়ান।[M ] Perl [sid_com]: 0.0067
[M ] mawk - $(count+1)="=" [Steven Penny (variant)]: 0.0254
[M ] gawk - $(count+1)="=" [Steven Penny (variant)]: 0.0599
[S ] head + tr [eugene y]: 0.1143
[S, P] dd + tr [mklement0]: 0.1144
[S ] printf + tr [user332325]: 0.1164
[M, P] mawk - while loop [Steven Penny]: 0.1434
[M ] seq -f [Sam Salisbury]: 0.1452
[M ] jot -b [Stefan Ludwig]: 0.1690
[M ] printf + sed [user332325 (comment)]: 0.1735
[M ] yes + head + tr [Digital Trauma]: 0.1883
[M, P] gawk - while loop [Steven Penny]: 0.2493
[M ] awk - $(count+1)="=" [Steven Penny (variant)]: 0.2614
[M, P] awk - while loop [Steven Penny]: 0.3211
[M, P] printf %.s= [dogbane]: 2.4565
[M ] echo -n - brace expansion loop [eugene y]: 7.5877
[M ] echo -n - arithmetic loop [Eliah Kagan]: 13.5426
[M ] printf + bash global substr. replacement [Tim]: n/a
${foo// /=}
) বড় স্ট্রিং দিয়ে অবিস্মরণীয়ভাবে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে কাটবে যেটি খুব ভাল স্ট্রিংয়ের সাথে মিলিয়ে যাবে Bash এটি শেষ)।(( i= 0; ... ))
) ব্রেস-প্রসারিতগুলির চেয়ে ধীরে ধীরে ( {1..n}
) - যদিও পাটিগণিত লুপগুলি আরও মেমরি-দক্ষ।awk
বিএসডি awk
(ওএসএক্স-তেও পাওয়া যায়) বোঝায় - এটি gawk
(জিএনইউ আওক) এর চেয়ে লক্ষণীয়ভাবে ধীর এবং বিশেষত mawk
।এখানে বাশ স্ক্রিপ্ট ( testrepeat
) যা উপরের উত্পাদন করেছে। এটি 2 টি আর্গুমেন্ট লাগে:
অন্য কথায়: উপরের সময়গুলি সাথে testrepeat 100 1000
এবং প্রাপ্ত হয়েছিলtestrepeat 1000000 1000
#!/usr/bin/env bash
title() { printf '%s:\t' "$1"; }
TIMEFORMAT=$'%6Rs'
# The number of repetitions of the input chars. to produce
COUNT_REPETITIONS=${1?Arguments: <charRepeatCount> [<testRunCount>]}
# The number of test runs to perform to derive the average timing from.
COUNT_RUNS=${2:-1}
# Discard the (stdout) output generated by default.
# If you want to check the results, replace '/dev/null' on the following
# line with a prefix path to which a running index starting with 1 will
# be appended for each test run; e.g., outFilePrefix='outfile', which
# will produce outfile1, outfile2, ...
outFilePrefix=/dev/null
{
outFile=$outFilePrefix
ndx=0
title '[M, P] printf %.s= [dogbane]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
# !! In order to use brace expansion with a variable, we must use `eval`.
eval "
time for (( n = 0; n < COUNT_RUNS; n++ )); do
printf '%.s=' {1..$COUNT_REPETITIONS} >"$outFile"
done"
title '[M ] echo -n - arithmetic loop [Eliah Kagan]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
for ((i=0; i<COUNT_REPETITIONS; ++i)); do echo -n =; done >"$outFile"
done
title '[M ] echo -n - brace expansion loop [eugene y]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
# !! In order to use brace expansion with a variable, we must use `eval`.
eval "
time for (( n = 0; n < COUNT_RUNS; n++ )); do
for i in {1..$COUNT_REPETITIONS}; do echo -n =; done >"$outFile"
done
"
title '[M ] printf + sed [user332325 (comment)]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
printf "%${COUNT_REPETITIONS}s" | sed 's/ /=/g' >"$outFile"
done
title '[S ] printf + tr [user332325]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
printf "%${COUNT_REPETITIONS}s" | tr ' ' '=' >"$outFile"
done
title '[S ] head + tr [eugene y]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
head -c $COUNT_REPETITIONS < /dev/zero | tr '\0' '=' >"$outFile"
done
title '[M ] seq -f [Sam Salisbury]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
seq -f '=' -s '' $COUNT_REPETITIONS >"$outFile"
done
title '[M ] jot -b [Stefan Ludwig]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
jot -s '' -b '=' $COUNT_REPETITIONS >"$outFile"
done
title '[M ] yes + head + tr [Digital Trauma]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
yes = | head -$COUNT_REPETITIONS | tr -d '\n' >"$outFile"
done
title '[M ] Perl [sid_com]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
perl -e "print \"=\" x $COUNT_REPETITIONS" >"$outFile"
done
title '[S, P] dd + tr [mklement0]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
dd if=/dev/zero bs=$COUNT_REPETITIONS count=1 2>/dev/null | tr '\0' "=" >"$outFile"
done
# !! On OSX, awk is BSD awk, and mawk and gawk were installed later.
# !! On Linux systems, awk may refer to either mawk or gawk.
for awkBin in awk mawk gawk; do
if [[ -x $(command -v $awkBin) ]]; then
title "[M ] $awkBin"' - $(count+1)="=" [Steven Penny (variant)]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
$awkBin -v count=$COUNT_REPETITIONS 'BEGIN { OFS="="; $(count+1)=""; print }' >"$outFile"
done
title "[M, P] $awkBin"' - while loop [Steven Penny]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
time for (( n = 0; n < COUNT_RUNS; n++ )); do
$awkBin -v count=$COUNT_REPETITIONS 'BEGIN { while (i++ < count) printf "=" }' >"$outFile"
done
fi
done
title '[M ] printf + bash global substr. replacement [Tim]'
[[ $outFile != '/dev/null' ]] && outFile="$outFilePrefix$((++ndx))"
# !! In Bash 4.3.30 a single run with repeat count of 1 million took almost
# !! 50 *minutes*(!) to complete; n Bash 3.2.57 it's seemingly even slower -
# !! didn't wait for it to finish.
# !! Thus, this test is skipped for counts that are likely to be much slower
# !! than the other tests.
skip=0
[[ $BASH_VERSINFO -le 3 && COUNT_REPETITIONS -gt 1000 ]] && skip=1
[[ $BASH_VERSINFO -eq 4 && COUNT_REPETITIONS -gt 10000 ]] && skip=1
if (( skip )); then
echo 'n/a' >&2
else
time for (( n = 0; n < COUNT_RUNS; n++ )); do
{ printf -v t "%${COUNT_REPETITIONS}s" '='; printf %s "${t// /=}"; } >"$outFile"
done
fi
} 2>&1 |
sort -t$'\t' -k2,2n |
awk -F $'\t' -v count=$COUNT_RUNS '{
printf "%s\t", $1;
if ($2 ~ "^n/a") { print $2 } else { printf "%.4f\n", $2 / count }}' |
column -s$'\t' -t
In order to use brace expansion with a variable, we must use `eval`
👍
এটি করার একাধিক উপায় রয়েছে।
একটি লুপ ব্যবহার:
ব্রেস সম্প্রসারণ পূর্ণসংখ্যার আক্ষরিক সাথে ব্যবহার করা যেতে পারে:
for i in {1..100}; do echo -n =; done
সি-এর মতো লুপ ভেরিয়েবলগুলির ব্যবহারের অনুমতি দেয়:
start=1
end=100
for ((i=$start; i<=$end; i++)); do echo -n =; done
printf
বিল্টিন ব্যবহার করে :
printf '=%.0s' {1..100}
এখানে একটি নির্ভুলতা নির্দিষ্ট করে নির্দিষ্ট বর্ণের ( 0
) প্রস্থের মাপসই স্ট্রিংটি কেটে দেওয়া হয় । হিসাবে printf
পুনঃব্যবহৃত হয়নি ফরম্যাট স্ট্রিং এর সব আর্গুমেন্ট গ্রাস, এই কেবল ছাপে "="
100 বার।
head
( printf
ইত্যাদি) এবং ব্যবহার করে tr
:
head -c 100 < /dev/zero | tr '\0' '='
printf %100s | tr " " "="
head
/ tr
সলিউশনের জন্য, যা উচ্চ পুনরাবৃত্তি গণনাগুলির সাথেও ভাল কাজ করে (ছোট ক্যাভ্যাট: head -c
পসিক্স-অনুগত নয়, তবে বিএসডি এবং জিএনইউ উভয়ই head
এটি প্রয়োগ করে); যদিও অন্য দুটি সমাধান সেক্ষেত্রে ধীর হবে, তবে তাদের মাল্টি- চ্যাটার স্ট্রিংগুলির সাথেও কাজ করার সুবিধা রয়েছে ।
yes
এবং head
- দরকারী yes "" | head -n 100
। tr
এটি যে কোনও অক্ষর মুদ্রণ করতে পারে:yes "" | head -n 100 | tr "\n" "="; echo
dd if=/dev/zero count=1 bs=100000000 | tr '\0' '=' >/dev/null
তুলনায় উল্লেখযোগ্যভাবে ধীর head -c100000000 < /dev/zero | tr '\0' '=' >/dev/null
। সময়ের পার্থক্য যথাযথভাবে পরিমাপ করতে আপনাকে অবশ্যই 100M + এর একটি ব্লক আকার ব্যবহার করতে হবে। 100 এম বাইটগুলি দুটি স্বতন্ত্র সংস্করণ দেখানো সহ 1.7 s এবং 1 এস নেয়। আমি /dev/null
টিআরটি খুলে কেবল এটিকে ফেলে দিয়েছিলাম এবং সংস্করণটির জন্য head
0.287 এস dd
এবং এক বিলিয়ন বাইটের জন্য সংস্করণটির জন্য 0.675 এস পেয়েছি ।
dd if=/dev/zero count=1 bs=100000000 | tr '\0' '=' >/dev/null
=> 0,21332 s, 469 MB/s
; এর জন্য: dd if=/dev/zero count=100 bs=1000000| tr '\0' '=' >/dev/null
=> 0,161579 s, 619 MB/s
;
সেক ব্যবহার করে এটি করার একটি গুরুতর সহজ উপায় আমি সবেমাত্র পেয়েছি:
আপডেট: এটি BSD এ কাজ করে যা seq
অন্যান্য সংস্করণ সহ ওএস এক্স.ওয়াইএমএমভি সহ আসে
seq -f "#" -s '' 10
'#' 10 বার প্রিন্ট করবে:
##########
-f "#"
সংখ্যাগুলিকে উপেক্ষা করার জন্য বিন্যাসের স্ট্রিং সেট করে এবং কেবলমাত্র #
প্রতিটিটির জন্য মুদ্রণ করে।-s ''
প্রতিটি সংখ্যাগুলির মধ্যে সেকশন অন্তর্ভুক্ত করা নতুন লাইনগুলি সরাতে পৃথককে একটি খালি স্ট্রিংয়ে সেট করে-f
এবং পরে স্থানগুলি -s
গুরুত্বপূর্ণ বলে মনে হচ্ছে।সম্পাদনা: এখানে এটি একটি কার্যকর কার্যক্রমে ...
repeat () {
seq -f $1 -s '' $2; echo
}
যাকে আপনি এভাবে কল করতে পারেন ...
repeat "#" 10
দ্রষ্টব্য: আপনি যদি পুনরাবৃত্তি করছেন #
তবে উদ্ধৃতিগুলি গুরুত্বপূর্ণ!
seq: format ‘#’ has no % directive
। seq
সংখ্যার জন্য, স্ট্রিং নয়। দেখুন gnu.org/software/coreutils/manual/html_node/seq-invocation.html
seq
করা হচ্ছে : ফর্ম্যাট স্ট্রিংটি পাস হয়েছে - সাধারণত উত্পন্ন হওয়া সংখ্যার ফর্ম্যাট করতে ব্যবহৃত হয় - কেবলমাত্র এখানে প্রতিলিপি করার জন্য স্ট্রিং থাকে যাতে আউটপুটটিতে কেবল স্ট্রিংয়ের অনুলিপি থাকে। দুর্ভাগ্যক্রমে, জিএনইউ ফর্ম্যাট স্ট্রিংয়ে একটি সংখ্যা বিন্যাসের উপস্থিতিতে জোর দেয় , যা আপনি দেখছেন ত্রুটি। -f
seq
"$1"
(ডাবল উক্তি) ব্যবহার করুন , যাতে আপনি '*'
এমবেডড হোয়াইটস্পেসের মতো অক্ষরে এবং স্ট্রিংগুলিতেও যেতে পারেন । অবশেষে, আপনি যদি ব্যবহার করতে সক্ষম হতে চাই %
, আপনি করতে হবে দ্বিগুণ করে (অন্যথায় seq
হবে মনে হয় এটা এর যেমন একটি বিন্যাসে স্পেসিফিকেশন অংশ %f
); ব্যবহার করে "${1//%/%%}"
যে যত্ন নিতে হবে। যেহেতু (যেমন আপনি উল্লেখ করেছেন) আপনি বিএসডি ব্যবহার করছেন seq
, এটি বিএসডি-এর মতো সাধারণ ওএসগুলিতে (যেমন, ফ্রিবিএসডি) কাজ করবে - বিপরীতে, এটি লিনাক্সে কাজ করবে না , যেখানে জিএনইউ seq
ব্যবহৃত হয়।
আকর্ষণীয় দুটি উপায় এখানে:
উবুন্টু @ উবুন্টু: ~ $ হ্যা = | মাথা -10 | পেস্ট-এস-ডি '' - ========== উবুন্টু @ উবুন্টু: ~ $ হ্যা = | মাথা -10 | tr -d "\ n" ========== উবুন্টু @ উবুন্টু: ~ $
দ্রষ্টব্য এই দুটি সূক্ষ্মভাবে পৃথক - paste
পদ্ধতিটি একটি নতুন লাইনে শেষ হয়। tr
পদ্ধতি না।
paste
অস্বাভাবিক প্রয়োজন -d '\0'
একটি খালি বিভেদক নির্দিষ্ট জন্য, এবং সঙ্গে ব্যর্থ -d ''
- -d '\0'
সব POSIX সামঞ্জস্যপূর্ণ বুদ্ধি কাজ করা উচিত paste
বাস্তবায়নের এবং প্রকৃতপক্ষে সঙ্গে কাজ করে গনুহ paste
খুব।
yes | mapfile -n 100 -C 'printf = \#' -c 1
time yes = | head -500 | paste -s -d '\0' -; time yes | mapfile -n 500 -C 'printf = \#' -c 1
। আরও গুরুত্বপূর্ণ, তবে: আপনি যদি printf
যাইহোক ব্যবহার করছেন তবে আপনি গ্রহণযোগ্য উত্তর থেকে সহজ এবং আরও কার্যকর উভয় পদ্ধতির সাথে যেতে পারেন:printf '%.s=' $(seq 500)
কোন সহজ উপায় নেই। লুপগুলি ব্যবহার printf
এবং প্রতিস্থাপন এড়িয়ে চলুন ।
str=$(printf "%40s")
echo ${str// /rep}
# echoes "rep" 40 times.
repl = 100
\n
repl() { local ts=$(printf "%${2}s"); printf %s "${ts// /$1}"; }
আপনি যদি POSIX- সম্মতি এবং সামঞ্জস্যতা echo
এবং printf
এবং / অথবা কেবলমাত্র বাদে অন্য শেলগুলির বিভিন্ন বাস্তবায়ন জুড়ে সঙ্গতি চান তবে bash
:
seq(){ n=$1; while [ $n -le $2 ]; do echo $n; n=$((n+1)); done ;} # If you don't have it.
echo $(for each in $(seq 1 100); do printf "="; done)
... perl -E 'say "=" x 100'
প্রায় সব জায়গায় একই আউটপুট উত্পাদন করবে ।
seq
কোনও পসিক্স ইউটিলিটি নয় (যদিও বিএসডি এবং লিনাক্স সিস্টেমগুলির এটির প্রয়োগ রয়েছে) - আপনি while
@ Xennex81 এর উত্তর printf "="
হিসাবে (এর পরিবর্তে আপনি সঠিকভাবে পরামর্শ দিচ্ছেন) এর পরিবর্তে লুপ দিয়ে পসিক্স শেল গাণিতিক করতে পারেন echo -n
।
cal
পসিক্স seq
এটি না. যাইহোক, কিছুক্ষণ লুপের সাথে উত্তরটি পুনরায় লেখার পরিবর্তে (যেমন আপনি বলেছেন যে এটি ইতিমধ্যে অন্যান্য উত্তরে রয়েছে) আমি একটি আরওয়াই ফাংশন যুক্ত করব। আরও শিক্ষামূলক সেভাবে ;-)।
এটি কীভাবে করা যায় তা নিয়ে প্রশ্ন ছিল echo
:
echo -e ''$_{1..100}'\b='
এটি কেবল একই সাথে perl -E 'say "=" x 100'
তবে একই রকম করবে echo
।
না eval
, কোনও সাবশেল, কোনও বাহ্যিক সরঞ্জাম, কোনও ধনুর্বন্ধনী সম্প্রসারণ সহ একটি খাঁটি বাশ উপায় (যেমন, আপনার একটি পরিবর্তনশীলতে পুনরাবৃত্তি করার সংখ্যা থাকতে পারে):
যদি আপনাকে এমন একটি ভেরিয়েবল দেওয়া হয় n
যা একটি (অ-নেতিবাচক) সংখ্যা এবং একটি ভেরিয়েবলে প্রসারিত হয় pattern
, যেমন,
$ n=5
$ pattern=hello
$ printf -v output '%*s' "$n"
$ output=${output// /$pattern}
$ echo "$output"
hellohellohellohellohello
আপনি এটি দিয়ে একটি ফাংশন করতে পারেন:
repeat() {
# $1=number of patterns to repeat
# $2=pattern
# $3=output variable name
local tmp
printf -v tmp '%*s' "$1"
printf -v "$3" '%s' "${tmp// /$2}"
}
এই সেট সহ:
$ repeat 5 hello output
$ echo "$output"
hellohellohellohellohello
এই ছোট কৌশলটির জন্য আমরা এর printf
সাথে বেশ কিছু ব্যবহার করছি :
-v varname
: স্ট্যান্ডার্ড আউটপুটে মুদ্রণের পরিবর্তে, printf
বিন্যাসিত স্ট্রিংয়ের সামগ্রীটি ভেরিয়েবলের মধ্যে রাখবে varname
।printf
আর্গুমেন্টটি ফাঁকের সাথে সম্পর্কিত সংখ্যা মুদ্রণ করতে ব্যবহার করবে। যেমন, printf '%*s' 42
42 স্পেস মুদ্রণ করবে print${var// /$pattern}
প্রসারণ দ্বারা প্রতিস্থাপিত সমস্ত স্পেসের var
সাথে বিস্তারে প্রসারিত হবে $pattern
।অপ্রত্যক্ষ সম্প্রসারণ ব্যবহার tmp
করে আপনি repeat
ফাংশনের পরিবর্তনশীল থেকে মুক্তি পেতে পারেন :
repeat() {
# $1=number of patterns to repeat
# $2=pattern
# $3=output variable name
printf -v "$3" '%*s' "$1"
printf -v "$3" '%s' "${!3// /$2}"
}
bash
পরামিতি সম্প্রসারণ (প্রেক্ষাপটে 'র বিশ্বব্যাপী স্ট্রিং রিপ্লেসমেন্ট অপারেশন ${var//old/new}
) বিশেষ করে ধীর আছেন: excruciatingly ব্যাশ মন্থর 3.2.57
ব্যাশ, এবং ধীর 4.3.30
, একটি 3.2 GHz ইন্টেল কোর i5 মেশিনে আমার ওএসএক্স 10.10.3 সিস্টেমে অন্তত: সঙ্গে এক হাজারের গণনা, জিনিসগুলি ধীর ( 3.2.57
) / দ্রুত ( 4.3.30
): 0.1 / 0.004 সেকেন্ড। 10,000 টির তুলনায় 10,000 টির ফলন হ'ল: repeat 10000 = var
প্রায় 80 সেকেন্ড (!) বাশ 3.2.57
এবং প্রায় 0.3 সেকেন্ড ব্যাশে 4.3.30
(তার চেয়ে অনেক দ্রুত 3.2.57
, তবে ধীর)।
#!/usr/bin/awk -f
BEGIN {
OFS = "="
NF = 100
print
}
অথবা
#!/usr/bin/awk -f
BEGIN {
while (z++ < 100) printf "="
}
awk 'BEGIN { while (c++ < 100) printf "=" }'
। স্থিতিমাপ কর শেল ফাংশন মধ্যে আবৃত (ডাকা যেমন repeat 100 =
, উদাহরণস্বরূপ): repeat() { awk -v count="$1" -v txt=".$2" 'BEGIN { txt=substr(txt, 2); while (i++ < count) printf txt }'; }
। (ডামি .
উপসর্গ গৃহস্থালির কাজ এবং পরিপূরক substr
কল বাসদ মধ্যে একটি বাগ সমস্যা এড়ানোর জন্য প্রয়োজন হয় awk
, যেখানে একটি পরিবর্তনশীল মান ক্ষণস্থায়ী শুরু সঙ্গে =
বিরতি কমান্ড।)
NF = 100
সমাধান (যদিও 100 পেতে খুব চালাক =
, আপনি ব্যবহার করা আবশ্যক NF = 101
)। আদেশ সহকারে এটি বাসদ ক্র্যাশ হয় awk
(কিন্তু এটা দিয়ে খুব দ্রুত gawk
এবং সঙ্গে আরও দ্রুত mawk
), এবং যে POSIX আলোচনা তন্ন তন্ন বরাদ্দ করতে NF
, কিংবা ক্ষেত্র ব্যবহার BEGIN
ব্লক। আপনি এটিকে awk
সামান্য ঝাপটা দিয়ে BSD এ কাজ করতে পারেন : awk 'BEGIN { OFS = "="; $101=""; print }'
(তবে কৌতূহলজনকভাবে, BSD এ awk
যা লুপ সমাধানের চেয়ে দ্রুত নয়)। স্থিতিমাপ কর শেল সমাধান হিসাবে: repeat() { awk -v count="$1" -v txt=".$2" 'BEGIN { OFS=substr(txt, 2); $(count+1)=""; print }'; }
।
original-awk
বাসদ এর awk, যা, বিপর্যস্ত যদি এই চেষ্টা করতে চান রিপোর্ট করা হয়েছে অনুরূপ পুরোনো awk লিনাক্স অধীনে নাম। নোট করুন যে ক্র্যাশ করা সাধারণত একটি শোষণীয় বাগ খুঁজে পাওয়ার দিকে প্রথম ধাপ। এই উত্তরটি তাই নিরাপত্তাহীন কোডের প্রচার করছে promoting
original-awk
এটি মানসম্মত এবং প্রস্তাবিত নয়
awk NF=100 OFS='=' <<< ""
(ব্যবহার bash
এবং gawk
)
আমি অনুমান করি প্রশ্নের মূল উদ্দেশ্যটি কেবল শেলের অন্তর্নির্মিত কমান্ডগুলি দিয়ে এটি করা ছিল। সুতরাং for
লুপ এবং printf
গুলি বৈধ হবে, যখন rep
, perl
এবং jot
নীচে এটিও হবে না। তবুও, নিম্নলিখিত আদেশ
jot -s "/" -b "\\" $((COLUMNS/2))
উদাহরণস্বরূপ, এর উইন্ডো-বিস্তৃত লাইনটি মুদ্রণ করে \/\/\/\/\/\/\/\/\/\/\/\/
jot -s '' -b '=' 100
। সতর্কতাটি হ'ল যখন ওএসএক্স সহ বিএসডি-র মতো প্ল্যাটফর্মগুলি আসে jot
, লিনাক্স ডিস্ট্রোস আসে না ।
apt install athena-jot
করবে jot
।
অন্যরা যেমন বলেছে, ব্যাশ ব্রেস সম্প্রসারণে প্যারামিটার বিস্তারের পূর্ববর্তী , সুতরাং সীমাগুলিতে কেবল আক্ষরিক চিহ্ন থাকতে পারে। এবং পরিষ্কার সমাধান সরবরাহ করে তবে একেকটি সিস্টেম থেকে অন্য সিস্টেমে পুরোপুরি পোর্টেবল হয় না, এমনকি যদি আপনি প্রতিটিটিতে একই শেল ব্যবহার করছেন। (যদিও ক্রমবর্ধমান উপলভ্য; যেমন, ফ্রিবিএসডি 9.3 এবং উচ্চতর ক্ষেত্রে higher ) এবং অন্যান্য দিকনির্দেশের কাজ সবসময় কাজ করে তবে কিছুটা অচল থাকে।{m,n}
seq
jot
seq
eval
ভাগ্যক্রমে, বাশ লুপগুলির জন্য সি-স্টাইল সমর্থন করে (কেবল গণিতের এক্সপ্রেশন সহ)। সুতরাং এখানে একটি সংক্ষিপ্ত "বিশুদ্ধ বাশ" উপায়:
repecho() { for ((i=0; i<$1; ++i)); do echo -n "$2"; done; echo; }
এটি প্রথম আর্গুমেন্ট হিসাবে পুনরাবৃত্তির সংখ্যা এবং স্ট্রিংটিকে পুনরাবৃত্তি করতে হবে (যা কোনও একক চরিত্র হতে পারে, সমস্যা বর্ণনার মতো) সমস্যার সাথে দ্বিতীয় তর্ক হিসাবে। repecho 7 b
আউটপুট bbbbbbb
(একটি নতুন লাইন দ্বারা সমাপ্ত)।
ডেনিস উইলিয়ামসন দিয়েছেন মূলত তার চমৎকার উত্তরে চার বছর আগে এই সমাধান করতে শেল স্ক্রিপ্ট-এ পুনরাবৃত্তি অক্ষরের স্ট্রিং তৈরি করা হচ্ছে । আমার ফাংশন বডি সেখানে কোড থেকে কিছুটা পৃথক:
যেহেতু এখানে ফোকাসটি একটি একক চরিত্রের পুনরাবৃত্তি করার দিকে রয়েছে এবং শেলটি বাশ, এটি সম্ভবত echo
পরিবর্তে ব্যবহার করা নিরাপদ printf
। এবং আমি এই প্রশ্নে সমস্যার বিবরণটি পড়ে মুদ্রণের পক্ষে অগ্রাধিকার হিসাবে প্রকাশ করেছি echo
। উপরের ফাংশন সংজ্ঞা ব্যাশ এবং ksh93 এ কাজ করে । যদিও printf
এটি বেশি বহনযোগ্য (এবং সাধারণত এই ধরণের জিনিসটির জন্য ব্যবহার করা উচিত), echo
এর সিনট্যাক্সটি তর্কযোগ্যভাবে আরও পাঠযোগ্য।
কিছু echo
শেল'স বিল্টিনগুলি -
একটি বিকল্প হিসাবে নিজেই ব্যাখ্যা করে - যদিও ইনপুটটির জন্য স্টিডিন -
ব্যবহার করার সাধারণ অর্থ , এর পক্ষে সংবেদনহীন echo
। zsh এটি করে। এবং নিশ্চিতভাবেই রয়েছে echo
যেগুলি স্বীকৃতি দেয় না -n
, কারণ এটি মানক নয় । (অনেক বোর্ন-স্টাইলের শেলগুলি লুপগুলির জন্য সি-স্টাইলটি মোটেও গ্রহণ করে না, সুতরাং তাদের echo
আচরণ বিবেচনা করা উচিত নয়))
এখানে কাজটি ক্রমটি মুদ্রণ করা; সেখানে এটি একটি ভেরিয়েবলকে নির্ধারণ করা ছিল।
যদি $n
পুনরাবৃত্তির পছন্দসই সংখ্যা হয় এবং আপনার এটি পুনরায় ব্যবহার করতে হবে না এবং আপনি আরও ছোট কিছু চান:
while ((n--)); do echo -n "$s"; done; echo
n
অবশ্যই একটি পরিবর্তনশীল হতে হবে - এইভাবে অবস্থানগত পরামিতিগুলির সাথে কাজ করে না। $s
পুনরায় পাঠ্য হয়।
printf "%100s" | tr ' ' '='
সর্বোত্তম।
zsh
ঘটনাক্রমে কাজ করে। ইকো-ইন-এ-লুপ অ্যাপ্রোচ ছোট ছোট পুনরাবৃত্তি গণনাগুলির জন্য ভাল কাজ করে তবে বৃহত্তরগুলির জন্য ইউটিলিটির উপর ভিত্তি করে পসিক্স -কমপ্লায়েন্ট বিকল্প রয়েছে , যা @ স্লোমোজোর মন্তব্য দ্বারা প্রমাণিত হয়েছে।
(while ((n--)); do echo -n "$s"; done; echo)
echo
বিবেচনাধীন নয় , আপনি যদি এটিতে ব্যাশ ব্যবহার করেন তবে ব্যাশের একটি বিল্টিন রয়েছে যা সমর্থন করে -n
। আপনি যা বলছেন তার স্পিরিট একেবারে সঠিক। কমপক্ষে অ-ইন্টারেক্টিভ ব্যবহারে printf
প্রায় সর্বদা পছন্দ করা উচিত echo
। তবে আমি মনে করি না যে এটি echo
যে কোনও প্রশ্নের জন্য জিজ্ঞাসা করা হয়েছিল এবং তার কার্যকর হবে তা জানতে যথেষ্ট তথ্য দিয়েছিল এমন প্রশ্নের উত্তর দেওয়া কোনওভাবেই অনুচিত বা বিভ্রান্তিমূলক ছিল । দয়া করে নোট করুন যে ((n--))
(ক ছাড়াই $
) এর পক্ষে সমর্থন পসিক্স নিজেই গ্যারান্টিযুক্ত নয়।
পাইথন সর্বব্যাপী এবং সর্বত্র একই কাজ করে।
python -c "import sys; print('*' * int(sys.argv[1]))" "=" 100
অক্ষর এবং গণনা পৃথক পরামিতি হিসাবে পাস করা হয়।
python -c "import sys; print(sys.argv[1] * int(sys.argv[2]))" "=" 100
একটি নির্বিচারে স্ট্রিং n বার পুনরাবৃত্তি করার আর একটি উপায়:
পেশাদাররা:
কনস:
yes
কমান্ড প্রয়োজন।#!/usr/bin/sh
to_repeat='='
repeat_count=80
yes "$to_repeat" | tr -d '\n' | head -c "$repeat_count"
একটি এএনএসআই টার্মিনাল এবং মার্কিন-এএসসিআইআই অক্ষর পুনরাবৃত্তি করতে। আপনি একটি এএনএসআই সিএসআই এস্কেপ ক্রম ব্যবহার করতে পারেন। এটি একটি চরিত্র পুনরাবৃত্তি করার দ্রুততম উপায়।
#!/usr/bin/env bash
char='='
repeat_count=80
printf '%c\e[%db' "$char" "$repeat_count"
বা স্থিরভাবে:
80 বারের একটি লাইন মুদ্রণ করুন =
:
printf '=\e[80b\n'
সীমাবদ্ধতা:
repeat_char
এএনএসআই সিএসআই ক্রম বোঝে না ।repeat_char
এএনএসআই সিএসআই ক্রমটি পুনরাবৃত্ত অক্ষরে প্রসারিত করবে না ।আমি লিনাক্সের স্ক্রিন জুড়ে অক্ষরের একটি লাইন মুদ্রণ করতে যা ব্যবহার করি তা এখানে (টার্মিনাল / স্ক্রিনের প্রস্থের উপর ভিত্তি করে)
printf '=%.0s' $(seq 1 $(tput cols))
ব্যাখ্যা:
প্রদত্ত ক্রম হিসাবে একটি সমান চিহ্ন মুদ্রণ করুন:
printf '=%.0s' #sequence
কোনও কমান্ডের আউটপুট ব্যবহার করুন (এটি কমান্ড সাবস্টিটিউশন নামে পরিচিত একটি ব্যাশ বৈশিষ্ট্য):
$(example_command)
একটি সিকোয়েন্স দিন, আমি উদাহরণ হিসাবে 1 থেকে 20 ব্যবহার করেছি। চূড়ান্ত কমান্ডে 20 এর পরিবর্তে টিপুট কমান্ড ব্যবহার করা হয়:
seq 1 20
টার্মিনালে বর্তমানে ব্যবহৃত কলামগুলির সংখ্যা দিন:
tput cols
for i in {1..100}
do
echo -n '='
done
echo
আপনি যদি কোনও অক্ষরের n বারবার পুনরাবৃত্তি করতে চান তবে তার উপর নির্ভর করে কতগুলি পৃথক সংখ্যা বলা যায়, বলুন, আপনি যে স্ট্রিংয়ের দৈর্ঘ্য করতে পারেন তা নির্ভর করে:
#!/bin/bash
vari='AB'
n=$(expr 10 - length $vari)
echo 'vari equals.............................: '$vari
echo 'Up to 10 positions I must fill with.....: '$n' equal signs'
echo $vari$(perl -E 'say "=" x '$n)
এটি প্রদর্শিত হয়:
vari equals.............................: AB
Up to 10 positions I must fill with.....: 8 equal signs
AB========
length
সাথে কাজ করবে না expr
, আপনি সম্ভবত বোঝাতে চেয়েছিলেন n=$(expr 10 - ${#vari})
; যাইহোক, এটা ব্যাশ এর গাণিতিক সম্প্রসারণ ব্যবহার করতে সহজ এবং আরো দক্ষ করে: n=$(( 10 - ${#vari} ))
। এছাড়াও, আপনার উত্তরের মূলে রয়েছে খুব পার্ল পদ্ধতির যে ওপি বাশ বিকল্পের সন্ধান করছে।
এটিই এলিয়াহ কাগন যা করছিলেন তার দীর্ঘতর সংস্করণ:
while [ $(( i-- )) -gt 0 ]; do echo -n " "; done
অবশ্যই আপনি সেই জন্য প্রিন্টফ ব্যবহার করতে পারেন তবে আমার পছন্দ অনুসারে:
printf "%$(( i*2 ))s"
এই সংস্করণটি ড্যাশ সামঞ্জস্যপূর্ণ:
until [ $(( i=i-1 )) -lt 0 ]; do echo -n " "; done
আমি প্রথম নম্বর হিসাবে।
function repeatString()
{
local -r string="${1}"
local -r numberToRepeat="${2}"
if [[ "${string}" != '' && "${numberToRepeat}" =~ ^[1-9][0-9]*$ ]]
then
local -r result="$(printf "%${numberToRepeat}s")"
echo -e "${result// /${string}}"
fi
}
নমুনা রান
$ repeatString 'a1' 10
a1a1a1a1a1a1a1a1a1a1
$ repeatString 'a1' 0
$ repeatString '' 10
রেফারেন্স লিবিতে: https://github.com/gdbtek/linux-cookbooks/blob/master/libraries/util.bash
আমার উত্তরটি আরও জটিল, এবং সম্ভবত নিখুঁত নয়, তবে যারা বিপুল সংখ্যায় আউটপুট চেয়েছেন তাদের জন্য, আমি 3 সেকেন্ডের মধ্যে প্রায় 1 মিলিয়ন করতে সক্ষম হয়েছি।
repeatString(){
# argument 1: The string to print
# argument 2: The number of times to print
stringToPrint=$1
length=$2
# Find the largest integer value of x in 2^x=(number of times to repeat) using logarithms
power=`echo "l(${length})/l(2)" | bc -l`
power=`echo "scale=0; ${power}/1" | bc`
# Get the difference between the length and 2^x
diff=`echo "${length} - 2^${power}" | bc`
# Double the string length to the power of x
for i in `seq "${power}"`; do
stringToPrint="${stringToPrint}${stringToPrint}"
done
#Since we know that the string is now at least bigger than half the total, grab however many more we need and add it to the string.
stringToPrint="${stringToPrint}${stringToPrint:0:${diff}}"
echo ${stringToPrint}
}
সবচেয়ে সহজ হ'ল ব্যাশটিতে এই ওয়ান-লাইনারটি ব্যবহার করা:
seq 10 | xargs -n 1 | xargs -I {} echo -n ===\>;echo
বেশিরভাগ বিদ্যমান সমাধানগুলি {1..10}
শেলের সিনট্যাক্স সহায়তার উপর নির্ভর করে , যা bash
- এবং zsh
- নির্দিষ্ট এবং এটি tcsh
ওপেনবিএসডি ksh
এবং সর্বাধিক নন- ব্যাশে কাজ করে না sh
।
নিম্নলিখিত শেলগুলির ওএস এক্স এবং সমস্ত * বিএসডি সিস্টেমে কাজ করা উচিত; বাস্তবে, এটি বিভিন্ন ধরণের আলংকারিক স্থানের পুরো ম্যাট্রিক্স তৈরি করতে ব্যবহার করা যেতে পারে:
$ printf '=%.0s' `jot 64` | fold -16
================
================
================
================$
দুঃখের বিষয়, আমরা পেছনের নতুন লাইন পাই না; যা printf '\n'
ভাঁজ পরে অতিরিক্ত দ্বারা স্থির করা যেতে পারে :
$ printf "=%.0s" `jot 64` | fold -16 ; printf "\n"
================
================
================
================
$
তথ্যসূত্র:
আমার প্রস্তাব ( এন এর জন্য পরিবর্তনশীল মান গ্রহণ ):
n=100
seq 1 $n | xargs -I {} printf =