282 votes

Comment puis-je convertir les tabulations en espaces dans chaque fichier d'un répertoire ?

Comment puis-je convertir les tabulations en espaces dans chaque fichier d'un répertoire (éventuellement de manière récursive) ?

Par ailleurs, existe-t-il un moyen de définir le nombre d'espaces par tabulation ?

0 votes

Vous voulez remplacer les tabulations dans les fichiers ou les noms de fichiers ?

3 votes

pr est un merveilleux utilitaire pour cela. Voir cette réponse .

0 votes

Il est déconseillé de remplacer les tabulations par des espaces, car cela nuirait aux autres personnes qui travaillent avec les mêmes fichiers. Il suffit d'ajuster les outils pour obtenir la largeur de tabulation souhaitée.

372voto

Gene Points 20184

Remplacement simple par sed est acceptable mais n'est pas la meilleure solution possible. S'il y a des espaces "supplémentaires" entre les tabulations, ils seront toujours présents après la substitution, et les marges seront donc irrégulières. Les tabulations développées au milieu des lignes ne fonctionneront pas non plus correctement. Dans bash on peut dire à la place

find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;

pour appliquer expand à chaque fichier Java dans l'arborescence du répertoire courant. Supprimez / remplacez le -name si vous ciblez d'autres types de fichiers. Comme le mentionne un des commentaires, soyez très prudent lorsque vous supprimez -name ou en utilisant un caractère générique faible. Vous pouvez facilement bloquer le référentiel et d'autres fichiers cachés sans intention. C'est pourquoi la réponse originale incluait ceci :

Vous devriez toujours faire une copie de sauvegarde de l'arbre avant d'essayer quelque chose comme ça, au cas où quelque chose se passerait mal.

0 votes

Quelqu'un pourrait-il expliquer pourquoi il faut utiliser le _ dans la commande, plutôt que de l'omettre et d'utiliser $0 ?

2 votes

@JeffreyMartinez Excellente question. gniourf_gniourf a modifié ma réponse originale le 11 novembre et a fait des remarques désobligeantes sur le fait qu'il ne connaissait pas la bonne façon d'utiliser {} . On dirait qu'il n'était pas au courant $0 cuando -c est utilisé. Puis dimo414 a modifié mon utilisation d'un temp dans le répertoire de conversion en /tmp qui sera beaucoup plus lent si /tmp est sur un point de montage différent. Malheureusement, je n'ai pas de boîte Linux disponible pour tester votre système. $0 proposition. Mais je pense que vous avez raison.

1 votes

@Gene, merci pour la clarification, ça ressemble bien à stackoverflow :p . Pendant que j'y suis, j'ajouterai que j'ai dû utiliser des guillemets autour de '*.java' pour un échappement correct de *.java.

212voto

kev Points 41855

Essayez l'outil de ligne de commande expand .

expand -i -t 4 input | sponge output

  • -i est utilisé pour développer uniquement les tabulations de tête sur chaque ligne ;
  • -t 4 signifie que chaque tabulation sera convertie en 4 caractères d'espacement (8 par défaut).
  • sponge provient de la moreutils et évite effacer le fichier d'entrée . Sous macOS, le paquet moreutils est disponible via Homebrew ( brew install moreutils ) ou MacPorts ( sudo port install moreutils ).

Enfin, vous pouvez utiliser gexpand sur macOS, après avoir installé coreutils con Homebrew ( brew install coreutils ) ou MacPorts ( sudo port install coreutils ).

6 votes

C'est l'un des GNU_Core_Utilities

2 votes

Et pour les systèmes qui n'utilisent pas les utilitaires de base de GNU, vous avez une chance décente de expand en cours d'installation puisqu'il est normalisé par la spécification Single Unix de The Open Group. Voir le numéro 6, qui date de 2001, bien que certaines mises à jour aient été appliquées, d'où l'année de publication 2004 : expand

34 votes

Vous devriez passer -i a expand pour ne remplacer que les tabulations de tête sur chaque ligne. Cela permet d'éviter de remplacer des tabulations qui pourraient faire partie du code.

72voto

Martin Beckett Points 60406

Avertissement : Cela va casser votre repo.

Este corrompra les fichiers binaires y compris ceux qui relèvent de l svn , .git ! Lisez les commentaires avant de l'utiliser !

find . -iname '*.java' -type f -exec sed -i.orig 's/\t/ /g' {} +

Le fichier original est enregistré sous le nom de [filename].orig .

Remplacez '*.java' par la terminaison du type de fichier que vous recherchez. De cette façon, vous pouvez éviter la corruption accidentelle de fichiers binaires.

Inconvénients :

  • Remplacera les tabulations partout dans un fichier.
  • Cela prendra beaucoup de temps si vous avez un dump SQL de 5 Go dans ce répertoire.

12 votes

Pour les espaces visuels qui sont un mélange de tabulations et d'espaces, cette approche donne une expansion incorrecte.

7 votes

J'ajouterais aussi un sélecteur de fichiers comme par exemple pour les fichiers .php seulement find ./ -iname "*.php" -type f -exec sed -i 's/ \t / /g' {} \ ;

102 votes

N'UTILISEZ PAS SED ! S'il y a une tabulation incorporée dans une chaîne de caractères, vous pouvez finir par altérer votre code. C'est ce que étendre était censée gérer. Utilisez expand .

5voto

drchuck Points 71

J'aime l'exemple "find" ci-dessus pour l'application récursive. Pour l'adapter de manière non récursive, en ne modifiant que les fichiers du répertoire actuel qui correspondent à un caractère générique, l'expansion globale du shell peut être suffisante pour de petites quantités de fichiers :

ls *.java | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}' | sh -v

Si vous voulez qu'il soit silencieux après avoir vérifié qu'il fonctionne, il suffit de laisser tomber l'élément -v sur le sh à la fin.

Bien sûr, vous pouvez choisir n'importe quel ensemble de fichiers dans la première commande. Par exemple, ne lister qu'un sous-répertoire particulier (ou des répertoires) de manière contrôlée comme ceci :

ls mod/*/*.php | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}' | sh

Ou, à son tour, exécuter find(1) avec une certaine combinaison de paramètres de profondeur, etc :

find mod/ -name '*.php' -mindepth 1 -maxdepth 2 | awk '{print "expand -t 4 ", $0, " > /tmp/e; mv /tmp/e ", $0}' | sh

1 votes

Le shell globbing se brisera tôt ou tard, car le nombre total de noms de fichiers ne peut être que de ARG_MAX longueur. C'est 128k sur les systèmes Linux, mais j'ai rencontré cette limite suffisamment de fois pour ne pas compter sur le shell globbing.

1 votes

Vous n'avez pas vraiment besoin de les adapter. find peut être dit -maxdepth 1 et il ne traite que les entrées du répertoire en cours de modification, et non l'arbre entier.

4voto

Tyr Points 1336

J'ai utilisé astyle pour réindenter tout mon code C/C++ après avoir trouvé des tabulations et des espaces mélangés. Il dispose également d'options permettant de forcer un style d'accolade particulier si vous le souhaitez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X