¿Cómo puedo generar ceros a la izquierda en Ruby?


Estoy sacando un conjunto de archivos numerados de un script Ruby. Los números provienen de incrementar un contador, pero para que se ordenen bien en el directorio, me gustaría usar ceros a la izquierda en los nombres de archivo. En otras palabras

File_001...

En lugar de

File_1

¿Existe un simple modo de añadir ceros a la izquierda al convertir un número en una cadena? (Sé que puedo hacer " si menos de 10.... si es inferior a 100").

 193
Author: Andrew Marshall, 2009-10-09

5 answers

Si se conoce el número máximo de dígitos en el contador (por ejemplo, n = 3 para los contadores 1..876), se puede hacer

str = "file_" + i.to_s.rjust(n, "0")
 233
Author: alex.zherdev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-09 11:16:46

Utilice el operador % con una cadena:

irb(main):001:0> "%03d" % 5
=> "005"

El lado izquierdo es una cadena de formato printf, y el lado derecho puede ser una lista de valores, por lo que podría hacer algo como:

irb(main):002:0> filename = "%s/%s.%04d.txt" % ["dirname", "filename", 23]
=> "dirname/filename.0023.txt"

Aquí hay una hoja de trucos del formato printf que puede ser útil para formar su cadena de formato. El formato printf es originalmente de la función C printf, pero hay funciones de formateo similares disponibles en perl, ruby, python, java, php, etc.

 306
Author: Daniel Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-09 11:43:23

¿No puedes simplemente usar formato de cadena del valor antes de concatear el nombre del archivo?

"%03d" % number
 42
Author: Ólafur Waage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-02 06:07:15

Uso String#next como el contador.

>> n = "000"
>> 3.times { puts "file_#{n.next!}" }
file_001
file_002
file_003

next es relativamente 'inteligente', lo que significa que incluso puede ir para

>> n = "file_000"
>> 3.times { puts n.next! }
file_001
file_002
file_003
 23
Author: testr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-19 09:33:48

Como se indica en las otras respuestas, "%03d" % number funciona bastante bien, pero va en contra de la guía de estilo de ruby :

Favorecer el uso de sprintf y su formato de alias sobre el bastante string críptico # % method

Podemos obtener el mismo resultado de una manera más legible usando lo siguiente:

format('%03d', number)
 1
Author: Rodrigo Vasconcelos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-21 08:01:07