¿Hay una manera de imprimir mismo personaje en varias ocasiones en bash, al igual que se puede utilizar esta construcción para hacer esto en Python:imprimir un carácter repetidamente en bash
print('%' * 3)
da
%%%
¿Hay una manera de imprimir mismo personaje en varias ocasiones en bash, al igual que se puede utilizar esta construcción para hacer esto en Python:imprimir un carácter repetidamente en bash
print('%' * 3)
da
%%%
seguro, sólo tiene que utilizar printf
y un poco de manipulación de cadenas fiesta
$ s=$(printf "%-30s" "*")
$ echo "${s// /*}"
******************************
Debe haber un camino más corto, pero en la actualidad que es cómo lo haría. Usted puede hacer esto en una función que se puede almacenar en una biblioteca para uso futuro
printf_new() {
str=$1
num=$2
v=$(printf "%-${num}s" "$str")
echo "${v// /*}"
}
Prueba de funcionamiento:
$ printf_new "*" 20
********************
$ printf_new "*" 10
**********
$ printf_new "%" 10
%%%%%%%%%%
Es feo, pero se puede hacer así:
$ for a in `seq 5`; do echo -n %; done
%%%%%
Por supuesto, seq
es un profesional externo gramo (que probablemente tengas).
¿Por qué utilizar otro programa cuando simplemente puede escribir: 'para a en {1..5}; hacer eco -n%; done'.) –
Me di cuenta de que en un script, mi "solución" no funciona, aquí hay una solución. –
-1. Es más lento que 'printf"% 0.s %% "{1..5}', que a su vez es más lento que 'printf '% * s' 5 '' | tr '' '%''. – Deadcode
me gusta esto:
echo $(yes % | head -n3)
Es posible que no desea:
for ((i=0; i<3; i++)){
echo -ne "%"
}
Es posible que como este:
s=$(printf "%3s"); echo " ${s// /%}"
Fuente: http://dbaspot.com/shell/357767-bash-fast-way-repeat-string.html
También hay esta la forma, pero no es muy útil:
echo %{,,}
+1 para la combinación de 'sí' y' cabeza' – fmark
¡Eso es lo que usan ahora! Salí buscando '/ dev/y' y no pude encontrarlo en mi sistema moderno. –
Otra:
char='%'
count=5
result=$(printf "%${count}s" ' ')
echo -e ${result// /$char}
Es posible para obtener cualquier número de carácter cero (\0
) de /dev/zero
. Lo único que queda por hacer es
head -c 20 /dev/zero |tr '\0' '+'
Tenga en cuenta que head
y tr
son comandos externos. Para que se invoque en un proceso separado.
Es posible "optimizar" esta solución con caché de cadenas.
CACHE="$(head -c 1000 /dev/zero |tr '\0' '+')"
echo "${CACHE:0:10}"
echo "${CACHE:0:100}"
echo "${CACHE:0:300}"
Sólo hay bash
empotrados en el estado de eco. Entonces, podemos usarlo en ciclo.
Esto no funciona; entra en un bucle sin fin que da salida a un número ilimitado de caracteres, no a 20 según lo previsto. El comando correcto es 'head -c 20/dev/zero | tr '\ 0' '+''. – Deadcode
Esto parece ser un error tipográfico en la parte de ssvda. Debería ser 'head -c 20' para imprimir los primeros 20 caracteres. 'head -n 20' muestra las primeras 20 líneas. – Six
De hecho, hay una sola línea que puede hacer esto:
printf "%0.s-" {1..10}
impresiones
----------
Aquí está el desglose de los argumentos que se pasan a printf
:
printf
para truncar la cadena si es más largo que la longitud especificada, que es ceroprintf
, podría ser cualquier cosa (para un "%" debe evitarlo con otro "%" primero, es decir, "%%")printf
si darle más argumentos de los que se especifican en el formato cadena es volver al principio de la cadena de formato y ejecutarlo de nuevo.El resultado final de lo que está pasando aquí, entonces, es que usted está diciendo printf
que desea que se imprima una cadena de longitud cero sin caracteres adicionales si la cadena entregada es más largo que cero. Luego, después de esta cadena de longitud cero, imprima un "-" (o cualquier otro conjunto de caracteres). Luego le proporciona 10 argumentos, por lo que imprime 10 cadenas de longitud cero, cada una con un "-".
¡Es un trazador de líneas único que imprime cualquier número de caracteres que se repiten!
Editar:
Casualmente, si desea imprimir $variable
caracteres sólo hay que cambiar el argumento ligeramente para utilizar seq
en lugar de la expansión de llaves de la siguiente manera:
printf '%0.s-' $(seq 1 $variable)
Esto en cambio pasar argumentos " 1 2 3 4 ... $ variable "a printf
, imprimiendo con precisión $variable
instancias de" - "
Muy bien, pero esto no funciona en *** #!/Bin/sh *** pero solo en *** #!/Bin/bash *** –
Dado que esto usa un bash incorporado, para un pequeño número de los caracteres repetidos deberían ser más rápidos que los métodos que generan los procesos externos. Para números grandes, 'printf '% * s' 1000000 '' | tr '' '' '' y otros métodos son más rápidos. – Deadcode
Mi única pregunta es en qué situación te gustaría imprimir un personaje que se repite 1 millón de veces? Podrían ver otras operaciones, pero eso solo saturaría tu salida con personajes aparentemente sin sentido. – CaffeineConnoisseur
Aquí está la manera más simple de hacerlo
seq -s % 4|tr -d '[:digit:]'
en cuenta que habrá sólo un 3 '%' en la secuencia creada.
-1. Imprime una nueva línea principal, imprime un carácter menos que el número pasado, y es más lento que 'printf '% * s' 3 '' | tr '' '%''. – Deadcode
La respuesta actual aceptada para esta pregunta (por ghostdog74) proporciona un método que se ejecuta muy lentamente incluso para un número moderadamente alto de caracteres. La respuesta más votados (por CaffeineConnoisseur) es mejor, pero aún es bastante lenta.
Esto es lo que, en mis pruebas, ha ejecutado más rápido de todos (incluso más rápido que la versión de Python):
perl -E "print '*' x 1000"
En segundo lugar se ubicó el comando python:
python -c "print('*' * 1000)"
Si ninguno perl y python están disponibles, entonces este es el tercero mejor:
head -c 1000 /dev/zero | tr '\0' '*'
Y en cuarto lugar está el que u cantar la fiesta de printf
incorporada junto con tr
:
printf '%*s' 1000 | tr ' ' '*'
Y aquí está uno (de CaffeineConnoisseur 's respuesta) que está en el quinto lugar en la velocidad para un gran número de caracteres repetidos, pero podría ser más rápido para los números pequeños (debido a usar solamente una fiesta incorporado, y no generando un proceso externo):
printf '%.s*' {1..1000}
Suponiendo que '*' es el carácter que se está imprimiendo, ¿cuál es el propósito del '% .s' anterior en el ejemplo final? – Hashim
"% s" es una especificación de formato para printf, que simplemente significa cadena. Entre "%" y "s", puede establecer atributos de longitud para la cadena. Usando cualquiera "." o ".0" establecerá la longitud máxima de la cadena en cero, imprimiendo nada para esa cadena. En este ejemplo, el rango se expande a 1 2 3 4 5 ..... 98 99 100 y cada número se trata como una cadena de longitud cero. Esta es la forma de controlar el recuento de asteriscos impresos. –
#!/usr/bin/awk -f
BEGIN {
while (c++ < 3) printf "%"
}
Resultado
%%%
Puede evitar la subshell aquí si usa 'printf -v'. 'printf -v str '% -30s' ''; echo "$ {str ///*}" ' – kojiro
-1. Esto es muy lento, especialmente para> 1000 caracteres. Casi todo es más rápido, incluyendo 'printf '% .s *' {1..30}', o 'printf '% * s' 1000000 '' | tr '' '*'' para números grandes. – Deadcode
Printf_new falla en la tercera ejecución de prueba. Lo arreglaría así: 'printf -v v"% - * s "" $ num "" "; echo "$ {v ///$ str}" ' – jarno