Как удалить все завершающие пробелы всего проекта? Начиная с корневого каталога и удаляя конечные пробелы из всех файлов во всех папках.
Кроме того, я хочу иметь возможность напрямую изменять файл, а не просто выводить все на стандартный вывод.
Как удалить все завершающие пробелы всего проекта? Начиная с корневого каталога и удаляя конечные пробелы из всех файлов во всех папках.
Кроме того, я хочу иметь возможность напрямую изменять файл, а не просто выводить все на стандартный вывод.
Ответы:
Вот решение 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:]]*$//"
\+
вместо *
строки замены - в противном случае она будет соответствовать каждой отдельной строке.
sed: RE error: illegal byte sequence
ко мне.
export LANG=C
и попробуйте еще раз
export LC_CTYPE=C
найти здесь: stackoverflow.com/questions/19242275/…
Использование:
find . -type f -print0 | xargs -0 perl -pi.bak -e 's/ +$//'
если вы не хотите, чтобы файлы ".bak" создавались:
find . -type f -print0 | xargs -0 perl -pi -e 's/ +$//'
как пользователь zsh вы можете опустить вызов find и вместо этого использовать:
perl -pi -e 's/ +$//' **/*
Примечание: Для того, чтобы предотвратить уничтожение .git
каталога, попробуйте добавить: -not -iwholename '*.git*'
.
.git
каталогами, независимо от того, насколько глубоко они вложены.
find . -not \( -name .svn -prune -o -name .git -prune \) -type f -print0 | xargs -0 perl -pi -e 's/ +$//'
rsync -rv --exclude=.git repo/ repo2/
после чего локальные изменения repo
также были в (неповрежденном) repo2
.
Два альтернативных подхода, которые также работают с символами новой строки 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/'
В Баше:
find dir -type f -exec sed -i 's/ *$//' '{}' ';'
Примечание: Если вы используете .git
репозиторий, попробуйте добавить: -not -iwholename '.git'
.
Это сработало для меня в 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'
find dir -not -path '.git' -iname '*.py' -print0 | xargs -0 sed --in-place=.bak 's/[[:space:]]*$//'
. Замените dir
каталог, о котором идет речь, как верхний уровень для рекурсии.
sed -i .bak
? Разве не должно быть sed -i.bak
(без пробела)?
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
это чудесно. Использовал его в течение нескольких лет и доступен почти во всех репозиториях пакетов для большинства дистрибутивов.
ex
Попробуйте использовать редактор Ex (часть 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: /programming/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
Запустите этот сценарий из каталога, который вы хотите просканировать. В OSX в конце он удалит все файлы, заканчивающиеся на .bak
.
Или просто:
find . -type f -name "*.java" -exec perl -p -i -e "s/[ \t]$//g" {} \;
который рекомендуется в Spring Framework Code Style .
find . -type f -name "*.java" -exec perl -p -i -e "s/[ \t]$//g" {} \;
удаляет только один конечный пробел вместо всех.
В итоге я не использовал поиск и не создавал файлы резервных копий.
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:]]*$//"
-name "*.rb*"
В итоге я запустил это, которое представляет собой смесь версий 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, если она есть.
Edit : Сделано немного безопаснее после комментария, не позволяя принимать файлы с «.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'
Я использую регулярные выражения. 4 шага:
Это удаляет все конечные пробелы в конце каждой строки во всех файлах. И вы можете исключить некоторые файлы, которые не подходят для этой цели.
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:]
поскольку обычно не вижу вертикальных вкладок, каналов форм и неразрывных пробелов. Ваш размер может отличаться.
Вот что работает для меня (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
инструкциям по очистке .