Es simple. No puedo soportar cuando la gente usa espacios al nombrar archivos. A veces destruye los comandos de la consola y hace que la salida de ls sea fea.
El desafío es escribir un programa (solo caracteres ascii) que
- cambia el nombre de todos los archivos (incluidos los directorios) en el directorio actual a versiones con espacios eliminados o reemplazados por '_'
- en caso de colisión, debe agregar un identificador único (depende de usted)
- desciende recursivamente en todos los subdirectorios
Puede asumir nombres de ruta de estilo UNIX. ¿Quién necesitaría este programa en una máquina Windows de todos modos?
Este es el código de golf, el programa más corto gana (#ascii caracteres). Como odio tanto los espacios, cada espacio tiene que contarse dos veces.
Proporcione su idioma, puntaje, programa y una breve descripción de cómo ejecutarlo.
El programa debe compilarse y ejecutarse con un esfuerzo razonable en mi máquina Linux.
EDITAR: como Etan solicitó una estructura de archivos para las pruebas, aquí está el script que utilizo actualmente para crear un árbol de archivos adecuado:
#!/bin/bash
rm -r TestDir
touchfiles()
{
touch my_file
touch my__file
touch "my file"
touch "my file"
touch " my_file "
}
mkdir TestDir
cd TestDir
touchfiles
for dir in "Test Sub" Test_Sub "Te stSub" Te_stSub
do
mkdir "$dir"
cd "$dir"
touchfiles
cd ..
done
fuente

Respuestas:
Coreutils Zsh + GNU - 48 bytes (1 espacio)
Es extraño que odies los espacios (ASCII), pero estás bien con pestañas y líneas nuevas, pero supongo que se necesita todo tipo.
zmv resuelve muchos problemas de cambio de nombre de archivos de manera concisa (y solo un poco oscura). Sin embargo, insiste en que los objetivos sean únicos; Si bien puede agregar fácilmente sufijos únicos, agregar un sufijo solo si fuera necesario prácticamente requiere volver a hacer todo el trabajo. Entonces, en cambio, hago un bucle manualmente y confío en GNU mv para agregar un identificador único en caso de colisión (
--backupopción, más--no-target-directoryen caso de que un destino sea un directorio existente, ya que demvlo contrario se movería la fuente dentro de ese directorio).(od)es un calificador global para ordenar la salida con directorios que aparecen después de su contenido (como los de find-depth).Dincluye archivos de puntos en el globo.:hy:tson modificadores de historia similares adirnameybasename.mvse queja de que se llama para cambiar el nombre de los archivos a sí mismos, porque el globo incluye nombres de archivos sin espacios. Así es la vida.Versión sin golf:
fuente
zmvbombas antesmvtienen la oportunidad de resolver las colisiones. Ok, estoy haciendo esto manualmente. Resulta que tiene exactamente la misma longitud si me salto los archivos de puntos e incluso guarda un carácter si no lo hago.Bash 116 bytes, 16 espacios
No suprimí los errores para ganar un par de bytes más. Esto no tendrá ninguna colisión.
Si
findse puede esperar GNU no posix , esto se puede acortar aún más:Bash 110 bytes, 15 espacios
Eliminar espacios en lugar de reemplazarlos usa dos bytes menos:
Bash 108 bytes, 15 espacios
Nota: si se pueden usar pestañas en lugar de espacios, solo se necesita 1 espacio (el que está en la regla de coincidencia para la sustitución en la línea 2).
Gracias a Dennis por encontrar un error en la comilla doble (y proporcionar una solución)
fuente
-depthen GNU puede ser reemplazado por-d, aunque se queja de que está en desuso. No sé sobre las reglas del golf, ¿puedo hacer eso?bash -c 'B=${0##*/}...' {} \;en su lugar, que en realidad es más corto.Nvariable? Nunca se define ...Python 180 bytes
solo 2 espacios si usa tab para sangría :-)
fuente
Si el orden de los sufijos de archivos colisionados no necesita dar precedente al archivo preexistente, entonces lo siguiente funciona para mí:
bash / find / mv 84 bytes, 16 espacios
bash / find / mv 82 bytes, 14 espacios
Acurrucado
&¶ ahorrar dos bytes de espacio.bash / find / mv 60 bytes, 11 espacios
Elimina la protección contra errores para obtener errores de mv en archivos que no tienen espacios para comenzar.
Editar: se eliminaron las citas
{}según lo recordó Dennis. También se lefindpermite gritar sobre portabilidad y desaprobación en la versión más corta dondemvya se está gritando sobre mover un archivo encima de sí mismo.Edición 2: se agregó
-Talmvcomando para evitar anidar directorios en lugar de renombrar como lo señala pqnet. Se usó la expansión de llaves al costo de un personaje sobre el uso de un solo espacio.fuente
-dlugar de-depthy no necesita las comillas{}.-dconversación sobre la respuesta de pqnet pero pensé que, dado que estaba silenciando losmvgritos, evitaría losfindgritos. Aunque probablemente debería acortarlo por el grito. Y sí, siempre cito{}por alguna razón, aunque sé que no tienes que hacerlo en este caso. Fuerza de la costumbre, supongo.-Topción paramvevitar estoNodeJS - 209 bytes, 3 espacios en blanco
fuente
node file.jsTypeError: Object #<Object> has no method 'exists'. Adivina dónde: ¡está en la línea 1! : DBash - 86 bytes
fuente
--backupa--bBash + Perl
rename64(
renamees el script de Perl en Debian y derivados, no el comando util-linux).fuente
*debería ser{}, tal como está, esto solo cambia el nombre de los archivos cuyo nombre aparece en el directorio actual. Esto no agrega un sufijo en caso de colisión. Podría ahorrar bastante omitiendo,-name "* *"ya querenameignora silenciosamente los archivos cuyo nombre no se transforma.POSIX
sh+ GNUfind+ GNUmv67 bytes ASCII + un espacio (literal)No sé si encaja, pero con esto cualquier secuencia de espacios se elude a una sola
_, me gusta de todos modos. En realidad, cualquier secuencia, excepto los espacios iniciales / finales, es decir, se trunca automáticamente (lo que también es, creo, un comportamiento beneficioso) . Gracias a Gilles por señalar esto.Esto solo usa el separador de campo interno para separar los campos.
Es bastante ... hablador ...
...Oh hombre. Sabía que la ficha era barata, pero pensé que al menos era inteligente. Ahora llego tarde a la fiesta ...
fuente
IFScosita mágica ...$expandno (expandido)) y lo que acabo de mencionar. Mira aquí-execcon-execdir. Otra peculiaridad de laIFSque no menciona es que los espacios finales se eliminan. Tenga en cuenta que, como otros han notado, también necesita la-Topciónmv, para cuando el objetivo de unamvllamada es un directorio existente.sh -c 'mkdir -p ../newtree/"$0"; ln "$0"/* ../newtree/$0 {} \;y otros globos en unfind -type dcomando para crear un árbol reflejado de enlaces duros y luego operar en ellos, pero supongo que escribir un código de golf para una operación de movimiento. Buen punto sobre los espacios iniciales / finales, aunque creo que también es un comportamiento que preferiría.zshla función integrada dezmvpor ejemplo.PHP,
147145bytes,21 espacios-> 146función recursiva. Corre con
s(".");Recorrer los
globresultados para la ruta dada:fuente
Rubí 121
fuente
gam3.rb:5:in `rename': Directory not empty - ./Te stSub or ./Te_stSub (Errno::ENOTEMPTY) from gam3.rb:5 from /usr/lib/ruby/1.8/find.rb:39:in `find' from /usr/lib/ruby/1.8/find.rb:38:in `catch' from /usr/lib/ruby/1.8/find.rb:38:in `find' from gam3.rb:3Pitón, 187
165, más 22 puntos de penalización por los espacios.
166, usando el truco \ t de Emanuele :
¡Solo un espacio en este!
fuente
LiveScript - 166
(Reemplace los espacios con pestañas).
Basado en la versión optimizada de nderscore de la respuesta de cPu1 .
fuente
Bash 4+ 111 bytes
fuente
Groovy, 139 caracteressegún el comentario de @ edc65
Groovy, manejar colisiones, 259 caracteres
fuente
POSIX (Probado en zsh) + comandos básicos de Linux 151
fuente
$(ls -CR)Es completamente falso. La-copción es inútil, y-Robtiene archivos sin su directorio, lo cual no tiene sentido. Su arquitectura fundamentalmente no manejará nombres de archivos que contengan nuevas líneas. Necesitaset -fo de lo contrario los nombres de archivo que contienen comodines explotarán.exportes inútil Puedo ver vagamente lo que intentas hacer para uniquificar archivos, pero la tubería está mal.