Comment pourrais-je faire cela avec echo
?
Perl -E 'say "=" x 100'
Vous pouvez utiliser:
printf '=%.0s' {1..100}
Comment ça marche:
Bash se développe {1..100} pour que la commande devienne:
printf '=%.0s' 1 2 3 4 ... 100
J'ai défini le format de printf sur =%.0s
, ce qui signifie qu'il imprimera toujours un seul =
, quel que soit l'argument donné. Par conséquent, il imprime 100 =
s.
Pas facile. Mais par exemple:
seq -s= 100|tr -d '[:digit:]'
Ou peut-être une manière conforme aux normes:
printf %100s |tr " " "="
Il y a aussi un tput rep
, mais mes terminaux (xterm et linux) ne semblent pas le supporter :)
Il y a plus d'une façon de le faire.
Utilisation d'une boucle:
Le développement d'accolade peut être utilisé avec des littéraux entiers:
for i in {1..100}; do echo -n =; done
Une boucle de type C permet l'utilisation de variables:
start=1
end=100
for ((i=$start; i<=$end; i++)); do echo -n =; done
Utilisation de la variable printf
:
printf '=%.0s' {1..100}
Spécifier une précision ici tronque la chaîne pour l'adapter à la largeur spécifiée (0
). Comme printf
réutilise la chaîne de format pour utiliser tous les arguments, ceci imprime simplement "="
100 fois.
Utilisation de head
(printf
, etc.) et de tr
:
head -c 100 < /dev/zero | tr '\0' '='
printf %100s | tr " " "="
Je viens de trouver un moyen très simple de faire cela en utilisant seq:
UPDATE: Ceci fonctionne sur la BSD seq
fournie avec OS X. YMMV avec d'autres versions
seq -f "#" -s '' 10
Imprimera '#' 10 fois, comme ceci:
##########
-f "#"
définit la chaîne de formatage pour ignorer les nombres et imprimer #
pour chacun.-s ''
définit le séparateur sur une chaîne vide pour supprimer les nouvelles lignes insérées par seq entre chaque nombre-f
et -s
semblent être importants.EDIT: Le voici dans une fonction pratique ...
repeat () {
seq -f $1 -s '' $2; echo
}
Que vous pouvez appeler comme ça ...
repeat "#" 10
NOTE: Si vous répétez #
, les guillemets sont importants!
Voici deux façons intéressantes:
ubuntu @ ubuntu: ~ $ yes = | tête -10 | paste -s -d '' - ========== ubuntu @ ubuntu: ~ $ yes = | tête -10 | tr -d "\ n" ========== ubuntu @ ubuntu: ~ $
Notez que ces deux éléments sont légèrement différents. La méthode paste
se termine par une nouvelle ligne. La méthode tr
ne le fait pas.
Il n'y a pas de moyen simple. Évitez les boucles utilisant printf
et la substitution.
str=$(printf "%40s")
echo ${str// /rep}
# echoes "rep" 40 times.
#!/usr/bin/awk -f
BEGIN {
OFS = "="
NF = 100
print
}
Ou
#!/usr/bin/awk -f
BEGIN {
while (z++ < 100) printf "="
}
Si vous souhaitez une conformité et une cohérence POSIX entre les différentes implémentations de echo
et printf
et/ou de shells autres que 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)
... produira le même résultat que Perl -E 'say "=" x 100'
un peu partout.
Je suppose que le but initial de la question était de le faire uniquement avec les commandes intégrées du shell. Ainsi, for
boucles et printf
s seraient légitimes, alors que rep
, Perl
et jot
ci-dessous ne le seraient pas. Pourtant, la commande suivante
jot -s "/" -b "\\" $((COLUMNS/2))
par exemple, imprime une ligne de \/\/\/\/\/\/\/\/\/\/\/\/
dans toute la fenêtre
Une manière pure de Bash sans eval
, aucun sous-shell, aucun outil externe, aucune extension d'accolade (c'est-à-dire que vous pouvez avoir le nombre à répéter dans une variable):
Si on vous donne une variable n
qui se développe en un nombre (non négatif) et une variable pattern
, par exemple,
$ n=5
$ pattern=hello
$ printf -v output '%*s' "$n"
$ output=${output// /$pattern}
$ echo "$output"
hellohellohellohellohello
Vous pouvez créer une fonction avec ceci:
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}"
}
Avec cet ensemble:
$ repeat 5 hello output
$ echo "$output"
hellohellohellohellohello
Pour cette petite astuce, nous utilisons beaucoup printf
avec:
-v varname
: au lieu d’imprimer sur une sortie standard, printf
mettra le contenu de la chaîne formatée dans la variable varname
.printf
utilisera l'argument pour imprimer le nombre d'espaces correspondant. Par exemple, printf '%*s' 42
imprimera 42 espaces.${var// /$pattern}
passera à l'extension var
, tous les espaces étant remplacés par l'extension $pattern
.Vous pouvez également vous débarrasser de la variable tmp
de la fonction repeat
en utilisant l’extension indirecte:
repeat() {
# $1=number of patterns to repeat
# $2=pattern
# $3=output variable name
printf -v "$3" '%*s' "$1"
printf -v "$3" '%s' "${!3// /$2}"
}
repeat() {
# $1=number of patterns to repeat
# $2=pattern
printf -v "TEMP" '%*s' "$1"
echo ${TEMP// /$2}
}
En bash 3.0 ou supérieur
for i in {1..100};do echo -n =;done
for i in {1..100}
do
echo -n '='
done
echo
La question était de savoir comment le faire avec echo
:
echo -e ''$_{1..100}'\b='
Cela fera exactement la même chose que Perl -E 'say "=" x 100'
mais avec echo
seulement.
Voici la version la plus longue de ce qu'Eliah Kagan épousait:
while [ $(( i-- )) -gt 0 ]; do echo -n " "; done
Bien sûr, vous pouvez utiliser printf pour cela aussi, mais pas vraiment à mon goût:
printf "%$(( i*2 ))s"
Cette version est compatible Dash:
until [ $(( i=i-1 )) -lt 0 ]; do echo -n " "; done
avec i étant le nombre initial.
Une alternative plus élégante à la solution Python proposée pourrait être:
python -c 'print "="*(1000)'
Comment pourrais-je faire cela avec écho?
Vous pouvez le faire avec echo
si la echo
est suivie de sed
:
echo | sed -r ':a s/^(.*)$/=\1/; /^={100}$/q; ba'
En fait, cette echo
n'est pas nécessaire ici.
Si vous souhaitez répéter un caractère n fois, n étant un nombre VARIABLE selon, par exemple, la longueur d'une chaîne, vous pouvez effectuer:
#!/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)
Il affiche:
vari equals.............................: AB
Up to 10 positions I must fill with.....: 8 equal signs
AB========
Une autre option consiste à utiliser GNU seq et à supprimer tous les nombres et toutes les lignes qu'il génère:
seq -f'#%.0f' 100 | tr -d '\n0123456789'
Cette commande imprime le caractère #
100 fois.
La plupart des solutions existantes dépendent toutes du support de la syntaxe {1..10}
du shell, qui est spécifique à bash
et zsh
et ne fonctionne pas dans tcsh
ou OpenBSD ksh
et la plupart des non-bash sh
.
Ce qui suit devrait fonctionner sous OS X et tous les systèmes * BSD de n’importe quel shell; en fait, il peut être utilisé pour générer toute une matrice de différents types d’espaces décoratifs:
$ printf '=%.0s' `jot 64` | fold -16
================
================
================
================$
Malheureusement, nous n’avons pas de nouvelle ligne; qui peut être corrigé par un printf '\n'
supplémentaire après le pli:
$ printf "=%.0s" `jot 64` | fold -16 ; printf "\n"
================
================
================
================
$
Références:
Python est omniprésent et fonctionne partout de la même manière.
python -c "import sys; print('*' * int(sys.argv[1]))" "=" 100
Caractère et nombre sont passés en tant que paramètres séparés.
Ma réponse est un peu plus compliquée et probablement pas parfaite, mais pour ceux qui cherchent à produire de grands nombres, j'ai pu faire environ 10 millions en 3 secondes.
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}
}
Le plus simple est d'utiliser ce one-liner dans bash:
seq 10 | xargs -n 1 | xargs -I {} echo -n ===\>;echo
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
}
Échantillons
$ repeatString 'a1' 10
a1a1a1a1a1a1a1a1a1a1
$ repeatString 'a1' 0
$ repeatString '' 10
Référence lib à: https://github.com/gdbtek/linux-cookbooks/blob/master/libraries/util.bash
Le plus simple est d'utiliser ce one-liner dans csh/tcsh:
printf "%50s\n" '' | tr '[:blank:]' '[=]'