C'est simple. Je ne peux pas rester debout lorsque des personnes utilisent des espaces pour nommer des fichiers. Cela détruit parfois les commandes de la console et rend la sortie de ls moche.
Le défi consiste à écrire un programme (uniquement des caractères ascii) qui
- renomme tous les fichiers (y compris les répertoires) du répertoire en cours en versions avec espaces supprimés ou remplacés par '_'
- en cas de collision, vous devez ajouter un identifiant unique (à vous de choisir)
- descend de manière récursive dans tous les sous-répertoires
Vous pouvez assumer des chemins d'accès de style UNIX. Qui aurait besoin de ce programme sur une machine Windows de toute façon?
C'est le code golf, le programme le plus court gagne (#ascii caractères). Comme je déteste tellement les espaces, chaque espace doit être compté deux fois.
Veuillez indiquer votre langue, votre score, votre programme et une brève description de son exécution.
Le programme doit compiler et exécuter avec un effort raisonnable sur ma machine Linux.
EDIT: Etan ayant demandé une structure de fichier pour les tests, voici le script que j’utilise actuellement pour créer une arborescence de fichiers appropriée:
#!/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
la source
Réponses:
Zsh + GNU coreutils - 48 octets (1 espace)
C'est bizarre que vous détestiez les espaces (ASCII), mais que vous utilisiez des tabulations et des nouvelles lignes, mais je suppose que cela prend toutes sortes de choses.
zmv résout un grand nombre de problèmes de changement de nom de fichier de manière concise (et de manière légèrement obscure). Cependant, il insiste sur le fait que les cibles sont uniques; Bien que vous puissiez facilement ajouter des suffixes uniques, ajouter un suffixe uniquement si cela est nécessaire nécessite pratiquement de refaire tout le travail. Donc, au lieu de cela, je boucle manuellement et je fais confiance à GNU mv pour ajouter un identifiant unique en cas de collision (
--backup
option, plus--no-target-directory
si la cible est un répertoire existant, sinonmv
, la source serait déplacée à l'intérieur de ce répertoire).(od)
est un qualificatif glob pour trier la sortie avec des répertoires apparaissant après leur contenu (comme dans find-depth
).D
inclut les fichiers de points dans le glob.:h
et:t
sont des modificateurs d’histoire similaires àdirname
etbasename
.mv
se plaint qu'il est appelé à renommer les fichiers eux-mêmes, parce que le glob comprend des noms de fichiers sans espaces. C'est la vie.Version non-golfée:
la source
zmv
bombes avantmv
ont une chance de régler les collisions. Ok, je le fais manuellement. Il s'avère que la longueur est exactement la même si je saute des fichiers à points et enregistre même un caractère si je ne le fais pas.Bash 116 octets, 16 espaces
Je n'ai pas supprimé les erreurs pour gagner quelques octets supplémentaires. Cela n'aura aucune collision.
Si un GNU non posix
find
peut être attendu, cela peut être raccourci davantage:Bash 110 octets, 15 espaces
Supprimer des espaces au lieu de les remplacer utilise deux octets de moins:
Bash 108 octets, 15 espaces
Remarque: si des tabulations peuvent être utilisées à la place d'espaces, un seul espace est nécessaire (celui de la règle de correspondance pour la substitution à la ligne 2).
Merci à Dennis d'avoir trouvé un bogue sur les guillemets doubles (et d'avoir fourni une solution)
la source
-depth
dans GNU peut être remplacé par-d
, bien qu'il se plaint qu'il est obsolète. Je ne connais pas les règles du golf, puis-je le faire?bash -c 'B=${0##*/}...' {} \;
place, ce qui est en fait plus court.N
variable? Ce n'est jamais défini ...Python 180 octets
seulement 2 espaces si vous utilisez la tabulation pour l'indentation :-)
la source
Si l'ordre des suffixes de fichiers entrés en collision n'a pas besoin de donner la priorité au fichier pré-existant, les opérations suivantes fonctionnent pour moi:
bash / find / mv 84 octets, 16 espaces
bash / find / mv 82 octets, 14 espaces
Cuddled
&&
pour économiser deux octets d'espace.bash / find / mv 60 octets, 11 espaces
Supprime la protection contre les erreurs afin que mv obtienne des erreurs sur les fichiers ne disposant pas d'espaces.
Edit: Supprimé les citations de
{}
comme rappelé par Dennis. Aussi autoriséfind
à crier sur la portabilité et la dépréciation dans la version la plus courte oùmv
crie déjà au sujet de déplacer un fichier sur lui-même.Edit 2: Ajouté
-T
à lamv
commande pour éviter les répertoires imbriqués au lieu de renommer comme indiqué par pqnet. Expansion d'accolade utilisée au coût d'un caractère sur seulement un espace.la source
-d
au lieu de-depth
et vous n'avez pas besoin des guillemets{}
.-d
conversation sur la réponse de pqnet, mais je me suis dit qu'étant donné que je faisais taire lesmv
cris, j'éviterais lesfind
cris. Bien que je devrais probablement le raccourcir pour celui qui crie. Et oui, je cite toujours{}
pour une raison quelconque, même si je sais que vous n'êtes pas obligé de le faire dans ce cas. Force d'habitude je suppose.-T
option pourmv
éviter ceciNodeJS - 209 octets, 3 espaces blancs
la source
node file.js
TypeError: Object #<Object> has no method 'exists'
. Devinez où: c'est dans la ligne 1! : DBash - 86 octets
la source
--backup
à--b
Bash + Perl
rename
64(
rename
est le script Perl sur Debian et ses dérivés, pas la commande util-linux.)la source
*
devrait être{}
, en l’état actuel, uniquement les fichiers dont le nom apparaît dans le répertoire en cours. Cela n’ajoute pas de suffixe en cas de collision. Vous pourriez économiser un peu en omettant-name "* *"
carrename
ignore les fichiers dont le nom n'est pas transformé.POSIX
sh
+ GNUfind
+ GNUmv
67 octets ASCII + un espace (littéral)Je ne sais pas si cela convient, mais avec cette séquence d'espaces est élidé pour un seul
_
- j'aime bien quand même. En fait, toute séquence, à l' exception des espaces de début / fin, est automatiquement tronquée (ce qui est également, je pense, un comportement bénéfique) . Merci à Gilles de l'avoir signalé.Cela utilise simplement le séparateur de champs interne pour séparer les champs.
C'est assez ... bavard ...
... oh mec. Je savais que la tabulation n'était pas chère, mais je pensais que c'était au moins intelligent. Maintenant je suis juste en retard à la fête ...
la source
IFS
truc magique ...$expand
pas exagérées ) et la chose ifsws que nous venons de mentionner. Regardez ici-exec
par-execdir
. Un autre problèmeIFS
que vous ne mentionnez pas est que les espaces de fin sont supprimés. Notez que, comme d'autres l'ont remarqué, vous devez également avoir l'-T
optionmv
, lorsque la cible d'unmv
appel est un répertoire existant.sh -c 'mkdir -p ../newtree/"$0"; ln "$0"/* ../newtree/$0 {} \;
et d'autres globs sur unefind -type d
commande pour créer un arbre en miroir de liens durs, puis d'opérer sur ceux-ci, mais je ne suis pas sûr d'écrire un code-golf pour une opération de déplacement. Un bon point à propos des espaces de début / fin, bien que je pense que c'est aussi un comportement que je préférerais.zsh
la fonction intégrée de,zmv
par exemple.PHP,
147145 octets,21 espaces-> 146fonction récursive. Courir avec
s(".");
Boucle à travers les
glob
résultats pour le chemin donné:la source
Ruby 121
la source
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:3
Python, 187
165, plus 22 points de pénalité pour les espaces.
166, en utilisant le truc d' Emanuele :
Un seul espace dans celui-ci!
la source
LiveScript - 166
(Remplacez les espaces par des tabulations.)
Basé sur la version optimisée de nderscore de la réponse de cPu1 .
la source
Bash 4+ 111 octets
la source
Groovy, 139 caractèresselon @ edc65 comment
Groovy, gérer les collisions, 259 caractères
la source
POSIX (testé sur zsh) + commandes Linux de base 151
la source
$(ls -CR)
est complètement faux. Cette-c
option est inutile et-R
vous permet d’obtenir des fichiers sans leur répertoire, ce qui est inutile. Fondamentalement, votre architecture ne gérera pas les noms de fichiers contenant des nouvelles lignes. Vous avez besoinset -f
sinon les noms de fichiers contenant des caractères génériques vont exploser.export
est inutile. Je vois vaguement ce que vous essayez de faire pour unifier des fichiers, mais la tuyauterie est fausse.