Ответ 1
Вот решение OS X >= 10.6 Snow Leopard.
Игнорирует папки .git и .svn и их содержимое. Также он не оставит резервный файл.
find . -not \( -name .svn -prune -o -name .git -prune \) -type f -print0 | xargs -0 sed -i '' -E "s/[[:space:]]*$//"
Как вы можете удалить все завершающие пробелы всего проекта? Запуск в корневом каталоге и удаление конечного пробела из всех файлов во всех папках.
Кроме того, я хочу, чтобы иметь возможность изменять файл напрямую, а не просто печатать все на stdout.
Вот решение OS X >= 10.6 Snow Leopard.
Игнорирует папки .git и .svn и их содержимое. Также он не оставит резервный файл.
find . -not \( -name .svn -prune -o -name .git -prune \) -type f -print0 | xargs -0 sed -i '' -E "s/[[:space:]]*$//"
Использование:
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*'
.
В Bash:
find dir -type f -exec sed -i 's/ *$//' '{}' ';'
Примечание. Если вы используете репозиторий .git
, попробуйте добавить: -not -iwholename '.git'
.
Два альтернативных подхода, которые также работают с DOS newlines (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 решение для репозитория, которое использует параметр -I
git grep
для пропуска файлов, которые Git считает двоичным:
git grep -I --name-only -z -e '' | xargs -0 sed -i 's/[ \t]\+\(\r\?\)$/\1/'
Это работало для меня в 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'
Для этой задачи была сделана Ack.
Он работает точно так же, как grep, но не знает, чтобы спускаться в такие места, как .svn,.git,.cvs и т.д.
ack --print0 -l '[ \t]+$' | xargs -0 -n1 perl -pi -e 's/[ \t]+$//'
Намного легче, чем прыгать через обручи с помощью find/grep.
Ack доступен через большинство менеджеров пакетов (как ack, так и ack-grep).
Это просто программа Perl, поэтому она также доступна в однофайловой версии, которую вы можете просто загрузить и запустить. Смотрите: Ack Install
В итоге я не использовал find и не создавал файлы резервных копий.
sed -i '' 's/[[:space:]]*$//g' **/*.*
В зависимости от глубины дерева файлов эта (более короткая версия) может быть достаточной для ваших нужд.
ПРИМЕЧАНИЕ. Это также принимает двоичные файлы, например.
Вместо того, чтобы исключать файлы, здесь приведено вышеописанное явно белое перечисление файлов на основе расширения файла, которое вы хотите удалить, не стесняясь к сезону:
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:]]*$//"
Я закончил работу над этим, это сочетание между версией 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: теперь он заменяет все виды пробелов в конце строки (что также означает вкладки)
Это хорошо работает.. add/remove --include для определенных типов файлов:
egrep -rl ' $' --include *.c * | xargs sed -i 's/\s\+$//g'
ex
Попробуйте использовать редактор Ex (часть Vim):
$ ex +'bufdo!%s/\s\+$//e' -cxa **/*.*
Примечание. Для рекурсии (bash4 и zsh) мы используем новую опцию globbing (**/*.*
). Включить 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
Для esing sed
, проверьте: Как удалить конечные пробелы с sed?
find
Найдите следующий script (например, remove_trail_spaces.sh
) для удаления конечных пробелов из файлов:
#!/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
Запустите этот script из каталога, который вы хотите отсканировать. В OSX в конце он удалит все файлы, заканчивающиеся на .bak
.
Или просто:
find . -type f -name "*.java" -exec perl -p -i -e "s/[ \t]$//g" {} \;
который рекомендуется использовать Spring Стиль кода рамки.
Ruby:
irb
Dir['lib/**/*.rb'].each{|f| x = File.read(f); File.write(f, x.gsub(/[ \t]+$/,"")) }
Это то, что работает для меня (Mac OS X 10.8, GNU sed, установленный 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/' \{} \;
Удалены конечные пробелы, заменяет вкладки пробелами, заменяет Windows CRLF на Unix \n
.
Интересно, что я должен запускать это 3-4 раза, прежде чем все файлы будут исправлены, всеми инструкциями по очистке gsed
.
1) Многие другие ответы используют -E
. Я не уверен, почему, как недокументированная BSD-совместимость. -r
следует использовать вместо этого.
2) В других ответах используется -i ''
. Это должно быть просто -i
(или -i''
, если оно выбрано), потому что -i
имеет суффикс сразу после.
3) 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]+$//'
Первый регистрирует псевдоним Git check-whitespace
, в котором перечислены файлы с завершающими пробелами.
Второй выполняется sed
на них.
Я использую \t
, а не [:space:]
, поскольку я обычно не вижу вертикальных вкладок, фидов форм и неразложимых пробелов. Ваше измерение может отличаться.