bash 如何递归删除所有文件的尾随空格?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/149057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to remove trailing whitespace of all files recursively?
提问by iamjwc
How can you remove all of the trailing whitespace of an entire project? Starting at a root directory, and removing the trailing whitespace from all files in all folders.
如何删除整个项目的所有尾随空格?从根目录开始,并从所有文件夹中的所有文件中删除尾随空格。
Also, I want to to be able to modify the file directly, and not just print everything to stdout.
另外,我希望能够直接修改文件,而不仅仅是将所有内容打印到标准输出。
回答by deepwell
Here is an OS X >= 10.6 Snow Leopard solution.
这是一个 OS X >= 10.6 Snow Leopard 解决方案。
It Ignores .git and .svn foldersand their contents. Also it won't leave a backup file.
它忽略 .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:]]*$//"
回答by Sec
Use:
用:
find . -type f -print0 | xargs -0 perl -pi.bak -e 's/ +$//'
if you don't want the ".bak" files generated:
如果您不想生成“.bak”文件:
find . -type f -print0 | xargs -0 perl -pi -e 's/ +$//'
as a zsh user, you can omit the call to find, and instead use:
作为 zsh 用户,您可以省略 find 调用,而是使用:
perl -pi -e 's/ +$//' **/*
Note: To prevent destroying .git
directory, try adding: -not -iwholename '*.git*'
.
注意:为防止破坏.git
目录,请尝试添加:-not -iwholename '*.git*'
.
回答by l0b0
Two alternative approaches which also work with DOS newlines(CR/LF) and do a pretty good job at avoiding binary files:
两种替代方法也适用于DOS 换行符(CR/LF)并且在避免二进制文件方面做得很好:
Generic solutionwhich checks that the MIME type starts with text/
:
检查 MIME 类型是否以以下开头的通用解决方案text/
:
while IFS= read -r -d '' -u 9
do
if [[ "$(file -bs --mime-type -- "$REPLY")" = text/* ]]
then
sed -i 's/[ \t]\+\(\r\?\)$//' -- "$REPLY"
else
echo "Skipping $REPLY" >&2
fi
done 9< <(find . -type f -print0)
Git repository-specificsolutionby Mat which uses the -I
option of git grep
to skip files which Git considers to be binary:
Mat 的Git 存储库特定解决方案,它使用 的-I
选项git grep
来跳过 Git 认为是二进制的文件:
git grep -I --name-only -z -e '' | xargs -0 sed -i 's/[ \t]\+\(\r\?\)$//'
回答by Adam Rosenfield
In Bash:
在 Bash 中:
find dir -type f -exec sed -i 's/ *$//' '{}' ';'
find dir -type f -exec sed -i 's/ *$//' '{}' ';'
Note: If you're using .git
repository, try adding: -not -iwholename '.git'
.
注意:如果您使用的是.git
存储库,请尝试添加:-not -iwholename '.git'
。
回答by pojo
This worked for me in OSX 10.5 Leopard, which does not use GNU sed or xargs.
这在 OSX 10.5 Leopard 中对我有用,它不使用 GNU sed 或 xargs。
find dir -type f -print0 | xargs -0 sed -i.bak -E "s/[[:space:]]*$//"
Just be careful with this if you have files that need to be excluded (I did)!
如果您有需要排除的文件(我做到了),请注意这一点!
You can use -prune to ignore certain directories or files. For Python files in a git repository, you could use something like:
您可以使用 -prune 忽略某些目录或文件。对于 git 存储库中的 Python 文件,您可以使用以下内容:
find dir -not -path '.git' -iname '*.py'
回答by jbbuckley
Ack was made for this kind of task.
Ack 就是为这种任务而制作的。
It works just like grep, but knows not to descend into places like .svn, .git, .cvs, etc.
它的工作方式与 grep 类似,但知道不会下降到 .svn、.git、.cvs 等位置。
ack --print0 -l '[ \t]+$' | xargs -0 -n1 perl -pi -e 's/[ \t]+$//'
Much easier than jumping through hoops with find/grep.
比使用 find/grep 跳过箍要容易得多。
Ack is available via most package managers (as either ackor ack-grep).
大多数包管理器都可以使用 Ack(作为ack或ack-grep)。
It's just a Perl program, so it's also available in a single-file version that you can just download and run. See: Ack Install
它只是一个 Perl 程序,因此它也有单文件版本,您只需下载并运行即可。请参阅:确认安装
回答by kenorb
ex
ex
Try using Ex editor(part of Vim):
尝试使用Ex 编辑器(Vim 的一部分):
$ ex +'bufdo!%s/\s\+$//e' -cxa **/*.*
Note: For recursion (bash4 & zsh), we use a new globbing option(**/*.*
). Enable by shopt -s globstar
.
注意:对于递归(bash4 和 zsh),我们使用新的通配选项( **/*.*
)。通过 启用shopt -s globstar
。
You may add the following function into your .bash_profile
:
您可以将以下功能添加到您的.bash_profile
:
# Strip trailing whitespaces.
# Usage: trim *.*
# See: https://stackoverflow.com/q/10711051/55075
trim() {
ex +'bufdo!%s/\s\+$//e' -cxa $*
}
sed
sed
For using sed
, check: How to remove trailing whitespaces with sed?
对于使用sed
,请检查:如何使用 sed 删除尾随空格?
find
find
Find the following script (e.g. remove_trail_spaces.sh
) for removing trailing whitespaces from the files:
找到以下脚本(例如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
Run this script from the directory which you want to scan. On OSX at the end, it will remove all the files ending with .bak
.
从要扫描的目录运行此脚本。最后在 OSX 上,它将删除所有以.bak
.
Or just:
要不就:
find . -type f -name "*.java" -exec perl -p -i -e "s/[ \t]$//g" {} \;
which is recommended way by Spring Framework Code Style.
这是Spring Framework Code Style推荐的方式。
回答by Jesper R?nn-Jensen
I ended up not using find and not creating backup files.
我最终没有使用 find 并且没有创建备份文件。
sed -i '' 's/[[:space:]]*$//g' **/*.*
Depending on the depth of the file tree, this (shorter version) may be sufficient for your needs.
根据文件树的深度,此(较短版本)可能足以满足您的需要。
NOTE this also takes binary files, for instance.
注意这也需要二进制文件,例如。
回答by ChicagoBob
Instead of excluding files, here is a variation of the above the explicitly white lists the files, based on file extension, that you want to strip, feel free to season to taste:
这里不是排除文件,而是上面明确的白名单文件的变体,基于文件扩展名,你想删除,随意调味:
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:]]*$//"
回答by odinho - Velmont
I ended up running this, which is a mix between pojo and adams version.
我最终运行了这个,它是 pojo 和 adams 版本之间的混合。
It will clean both trailing whitespace, and also another form of trailing whitespace, the carriage return:
它将清除尾随空格以及另一种形式的尾随空格,即回车:
find . -not \( -name .svn -prune -o -name .git -prune \) -type f \
-exec sed -i 's/[:space:]+$//' \{} \; \
-exec sed -i 's/\r\n$/\n/' \{} \;
It won't touch the .git folder if there is one.
如果有,它不会触及 .git 文件夹。
Edit: Made it a bit safer after the comment, not allowing to take files with ".git" or ".svn" in it. But beware, it willtouch binary files if you've got some. Use -iname "*.py" -or -iname "*.php"
after -type f
if you only want it to touch e.g. .py and .php-files.
编辑:在评论后让它更安全一点,不允许在其中使用“.git”或“.svn”的文件。但要注意,如果你有一些二进制文件,它会接触到二进制文件。如果您只希望它接触例如 .py 和 .php 文件,请使用-iname "*.py" -or -iname "*.php"
after -type f
。
Update 2: It now replaces all kinds of spaces at end of line (which means tabs as well)
更新 2:它现在替换行尾的各种空格(这也意味着制表符)