web-dev-qa-db-fra.com

Comment supprimer récursivement les espaces de fin de tous les fichiers?

Comment pouvez-vous supprimer tous les espaces de fin d'un projet entier? Démarrage à partir d'un répertoire racine et suppression de l'espace de fin de tous les fichiers de tous les dossiers.

De plus, je veux pouvoir modifier le fichier directement, et pas seulement tout imprimer sur stdout.

118
iamjwc

Voici une solution OS X> = 10.6 Snow Leopard.

Il ignore les dossiers .git et .svn et leur contenu. De plus, il ne laissera pas de fichier de sauvegarde.

export LC_CTYPE=C
export LANG=C
find . -not \( -name .svn -Prune -o -name .git -Prune \) -type f -print0 | xargs -0 sed -i '' -E "s/[[:space:]]*$//"
82
deepwell

Utilisation:

find . -type f -print0 | xargs -0 Perl -pi.bak -e 's/ +$//'

si vous ne voulez pas que les fichiers ".bak" soient générés:

find . -type f -print0 | xargs -0 Perl -pi -e 's/ +$//'

en tant qu'utilisateur zsh, vous pouvez omettre l'appel pour rechercher et utiliser à la place:

Perl -pi -e 's/ +$//' **/*

Remarque: pour éviter de détruire .git répertoire, essayez d'ajouter: -not -iwholename '*.git*'.

29
Sec

Deux approches alternatives qui fonctionnent également avec les sauts de ligne DOS (CR/LF) et font un assez bon travail pour éviter les binaires fichiers :

Solution générique qui vérifie que le type MIME commence par text/:

while IFS= read -r -d '' -u 9
do
    if [[ "$(file -bs --mime-type -- "$REPLY")" = text/* ]]
    then
        sed -i 's/[ \t]\+\(\r\?\)$/\1/' -- "$REPLY"
    else
        echo "Skipping $REPLY" >&2
    fi
done 9< <(find . -type f -print0)

Solution spécifique au référentiel Git par Mat qui utilise le -I option de git grep pour ignorer les fichiers que Git considère comme binaires:

git grep -I --name-only -z -e '' | xargs -0 sed -i 's/[ \t]\+\(\r\?\)$/\1/'
27
l0b0

Dans Bash:

find dir -type f -exec sed -i 's/ *$//' '{}' ';'

Remarque: Si vous utilisez .git référentiel, essayez d'ajouter: -not -iwholename '.git'.

22
Adam Rosenfield

Cela a fonctionné pour moi dans OSX 10.5 Leopard, qui n'utilise pas GNU sed ou xargs.

find dir -type f -print0 | xargs -0 sed -i.bak -E "s/[[:space:]]*$//"

Soyez prudent avec cela si vous avez des fichiers qui doivent être exclus (je l'ai fait)!

Vous pouvez utiliser -Prune pour ignorer certains répertoires ou fichiers. Pour les fichiers Python dans un référentiel git, vous pouvez utiliser quelque chose comme:

find dir -not -path '.git' -iname '*.py'
14
pojo

Ack a été fait pour ce genre de tâche.

Il fonctionne exactement comme grep, mais sait ne pas descendre dans des endroits comme .svn, .git, .cvs, etc.

ack --print0 -l '[ \t]+$' | xargs -0 -n1 Perl -pi -e 's/[ \t]+$//'

Beaucoup plus facile que de sauter à travers des cerceaux avec find/grep.

Ack est disponible via la plupart des gestionnaires de packages (sous la forme ack ou ack-grep ).

Ce n'est qu'un programme Perl, il est donc également disponible dans une version à fichier unique que vous pouvez simplement télécharger et exécuter. Voir: Ack Install

9
jbbuckley

ex

Essayez d'utiliser éditeur Ex (partie de Vim):

$ ex +'bufdo!%s/\s\+$//e' -cxa **/*.*

Remarque: Pour la récursivité (bash4 & zsh), nous utilisons ne nouvelle option de globbing (**/*.*). Activer par shopt -s globstar.

Vous pouvez ajouter la fonction suivante dans votre .bash_profile:

# Strip trailing whitespaces.
# Usage: trim *.*
# See: https://stackoverflow.com/q/10711051/55075
trim() {
  ex +'bufdo!%s/\s\+$//e' -cxa $*
}

sed

Pour utiliser sed, vérifiez: Comment supprimer les espaces de fin avec sed?

find

Recherchez le script suivant (par exemple remove_trail_spaces.sh) pour supprimer les espaces de fin des fichiers:

#!/bin/sh
# Script to remove trailing whitespace of all files recursively
# See: https://stackoverflow.com/questions/149057/how-to-remove-trailing-whitespace-of-all-files-recursively

case "$OSTYPE" in
  darwin*) # OSX 10.5 Leopard, which does not use GNU sed or xargs.
    find . -type f -not -iwholename '*.git*' -print0  | xargs -0 sed -i .bak -E "s/[[:space:]]*$//"
    find . -type f -name \*.bak -print0 | xargs -0 rm -v
    ;;
  *)
    find . -type f -not -iwholename '*.git*' -print0 | xargs -0 Perl -pi -e 's/ +$//'
esac

Exécutez ce script à partir du répertoire que vous souhaitez analyser. Sur OSX à la fin, il supprimera tous les fichiers se terminant par .bak.

Ou juste:

find . -type f -name "*.Java" -exec Perl -p -i -e "s/[ \t]$//g" {} \;

ce qui est recommandé par Spring Framework Code Style .

7
kenorb

Au lieu d'exclure des fichiers, voici une variante de ce qui précède, les listes explicitement blanches des fichiers, en fonction de l'extension de fichier, que vous souhaitez supprimer, n'hésitez pas à assaisonner au goût:

find . \( -name *.rb -or -name *.html -or -name *.js -or -name *.coffee -or \
-name *.css -or -name *.scss -or -name *.erb -or -name *.yml -or -name *.ru \) \
-print0 | xargs -0 sed -i '' -E "s/[[:space:]]*$//"
6
ChicagoBob

J'ai fini par ne pas utiliser find et ne pas créer de fichiers de sauvegarde.

sed -i '' 's/[[:space:]]*$//g' **/*.*

Selon la profondeur de l'arborescence des fichiers, cette (version plus courte) peut être suffisante pour vos besoins.

REMARQUE, cela prend également des fichiers binaires, par exemple.

6

J'ai fini par exécuter cela, qui est un mélange entre la version pojo et la version adams.

Il nettoiera à la fois les espaces de fin et également une autre forme d'espaces de fin, le retour chariot:

find . -not \( -name .svn -Prune -o -name .git -Prune \) -type f \
  -exec sed -i 's/[:space:]+$//' \{} \;  \
  -exec sed -i 's/\r\n$/\n/' \{} \;

Il ne touchera pas le dossier .git s'il en existe un.

Edit: Rendu un peu plus sûr après le commentaire, ne permettant pas de prendre des fichiers avec ".git" ou ".svn" dedans. Mais attention, il touchera les fichiers binaires si vous en avez. Utilisation -iname "*.py" -or -iname "*.php" après -type f si vous voulez seulement qu'il touche par exemple Fichiers .py et .php.

pdate 2: Il remplace désormais toutes sortes d'espaces en fin de ligne (ce qui signifie aussi les tabulations)

5
odinho - Velmont

Rubis:

irb
Dir['lib/**/*.rb'].each{|f| x = File.read(f); File.write(f, x.gsub(/[ \t]+$/,"")) }
4
grosser

Cela fonctionne bien .. ajouter/supprimer - inclure pour des types de fichiers spécifiques:

egrep -rl ' $' --include *.c *  | xargs sed -i 's/\s\+$//g'
4
Grant Murphy

1) De nombreuses autres réponses utilisent -E. Je ne sais pas pourquoi, car c'est compatibilité BSD non documentée option. -r devrait être utilisé à la place.

2) Les autres réponses utilisent -i ''. Cela devrait être juste -i (ou -i'' si vous préférez), car -i a le suffixe juste après.

3) Solution spécifique à Git:

git config --global alias.check-whitespace \
'git diff-tree --check $(git hash-object -t tree /dev/null) HEAD'

git check-whitespace | grep trailing | cut -d: -f1 | uniq -u -z | xargs -0 sed --in-place -e 's/[ \t]+$//'

Le premier enregistre un alias git check-whitespace qui répertorie les fichiers avec des espaces de fin. Le second exécute sed sur eux.

J'utilise uniquement \t plutôt que [:space:] car je ne vois généralement pas de tabulations verticales, de flux de formulaires et d'espaces insécables. Votre mesure peut varier.

2
Ondra Žižka

C'est ce qui fonctionne pour moi (Mac OS X 10.8, GNU sed installé par Homebrew):

find . -path ./vendor -Prune -o \
  \( -name '*.Java' -o -name '*.xml' -o -name '*.css' \) \
  -exec gsed -i -E 's/\t/    /' \{} \; \
  -exec gsed -i -E 's/[[:space:]]*$//' \{} \; \
  -exec gsed -i -E 's/\r\n/\n/' \{} \;

Suppression des espaces de fin, remplace les tabulations par des espaces, remplace Windows CRLF par Unix \n.

Ce qui est intéressant, c'est que je dois l'exécuter 3-4 fois avant que tous les fichiers ne soient corrigés, par toutes les instructions de nettoyage gsed.

1
yegor256

J'utilise des expressions régulières. 4 étapes:

  1. Ouvrez le dossier racine dans votre éditeur (j'utilise Visual Studio Code).
  2. Appuyez sur l'icône Rechercher à gauche et activez le mode d'expression régulière.
  3. Entrez "+\n" dans la barre de recherche et "\ n" dans la barre de remplacement.
  4. Cliquez sur "Remplacer tout".

Cela supprime tous les espaces de fin à la fin de chaque ligne dans tous les fichiers. Et vous pouvez exclure certains fichiers qui ne correspondent pas à ce besoin.

1
roedeercuco