Как рекурсивно удалить конечные пробелы из всех файлов? - PullRequest
117 голосов
/ 29 сентября 2008

Как вы можете удалить все конечные пробелы всего проекта? Начиная с корневого каталога и удаляя завершающие пробелы из всех файлов во всех папках.

Кроме того, я хочу иметь возможность изменять файл напрямую, а не просто распечатывать все в стандартный вывод.

Ответы [ 14 ]

81 голосов
/ 27 февраля 2011

Вот решение OS X> = 10.6 Snow Leopard.

Игнорирует папки .git и .svn и их содержимое. Также он не оставит файл резервной копии.

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:]]*$//"
29 голосов
/ 29 сентября 2008

Использование:

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

, если вы не хотите, чтобы генерировались файлы ".bak":

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

как пользователь zsh, вы можете опустить вызов, чтобы найти, и вместо этого использовать:

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

Примечание. Чтобы предотвратить уничтожение каталога .git, попробуйте добавить: -not -iwholename '*.git*'.

25 голосов
/ 12 апреля 2012

Два альтернативных подхода, которые также работают с символами новой строки DOS (CR / LF) и довольно неплохо работают на , избегая двоичных файлов :

Общее решение , которое проверяет, что тип MIME начинается с 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)

Git-специфичное решение от Mat, использующее -I опцию git grep для пропуска файлов, которые Git считает двоичными:

git grep -I --name-only -z -e '' | xargs -0 sed -i 's/[ \t]\+\(\r\?\)$/\1/'
22 голосов
/ 29 сентября 2008

В Баш:

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

Примечание. Если вы используете репозиторий .git, попробуйте добавить: -not -iwholename '.git'.

14 голосов
/ 12 марта 2009

Это сработало для меня в OSX 10.5 Leopard, которая не использует GNU sed или xargs.

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

Просто будьте осторожны с этим, если у вас есть файлы, которые нужно исключить (я сделал)!

Вы можете использовать -prune, чтобы игнорировать определенные каталоги или файлы. Для файлов Python в репозитории git вы можете использовать что-то вроде:

find dir -not -path '.git' -iname '*.py'
9 голосов
/ 27 апреля 2013

Ack был создан для такого рода задач.

Он работает точно так же, как grep, но не знает, как спускаться в такие места, как .svn, .git, .cvs и т. Д.

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

Гораздо проще, чем прыгать через обруч с помощью команды find / grep.

Ack доступен через большинство менеджеров пакетов (как ack или ack-grep ).

Это всего лишь Perl-программа, поэтому она также доступна в однофайловой версии, которую вы можете просто загрузить и запустить. См .: Подтверждение установки

7 голосов
/ 14 мая 2014

ex

Попробуйте использовать Ex editor (часть Vim):

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

Примечание. Для рекурсии (bash4 & zsh) мы используем новый параметр глобализации (**/*.*). Включить с помощью shopt -s globstar.

Вы можете добавить следующую функцию в .bash_profile:

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

sed

Для использования sed, проверьте: Как удалить конечные пробелы с помощью sed?

find

Найдите следующий скрипт (например, remove_trail_spaces.sh) для удаления конечных пробелов из файлов:

#!/bin/sh
# Script to remove trailing whitespace of all files recursively
# See: /139362/kak-rekursivno-udalit-konechnye-probely-iz-vseh-failov

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

Запустите этот скрипт из каталога, который вы хотите сканировать. В конце OSX удалит все файлы, заканчивающиеся на .bak.

или просто:

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

, рекомендуемый Spring Framework Code Style .

6 голосов
/ 09 марта 2012

Вместо того, чтобы исключать файлы, вот вариант из приведенных выше явных белых списков файлов, основанных на расширении файлов, которые вы хотите вырезать, не стесняйтесь приправить по вкусу:

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 голосов
/ 26 ноября 2009

Я закончил тем, что не использовал find и не создавал резервные файлы.

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

В зависимости от глубины дерева файлов, этого (более короткая версия) может быть достаточно для ваших нужд.

ПРИМЕЧАНИЕ. Для этого также требуются двоичные файлы, например.

5 голосов
/ 16 ноября 2010

Я закончил тем, что запустил это, что является смесью версии pojo и adams.

Он будет очищать как конечные пробелы, так и другую форму конечных пробелов, возврат каретки:

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

Она не коснется папки .git, если она есть.

Редактировать : Сделано немного безопаснее после комментария, не позволяя принимать файлы с ".git" или ".svn" в нем. Но будьте осторожны, будет касаться двоичных файлов, если они у вас есть. Используйте -iname "*.py" -or -iname "*.php" после -type f, если хотите, чтобы оно касалось, например, .py и .php-файлы.

Обновление 2 : теперь заменяет все виды пробелов в конце строки (что также означает табуляцию)

...