如何递归删除所有文件的尾随空格?

如何删除整个项目的所有尾随空格?从根目录开始,并从所有文件夹中的所有文件中删除尾随的空格。

另外,我希望能够直接修改该文件,而不仅仅是将所有内容打印到标准输出。

57670 次浏览

在 Bash:

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

注意: 如果您正在使用 .git存储库,请尝试添加: -not -iwholename '.git'

用途:

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*'

这在 OSX 10.5 Leopard 中对我很有用,它不使用 GNU sed 或 xargs。

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

如果您有需要排除的文件(我做到了) ,只是要小心这一点!

您可以使用-prune 来忽略某些目录或文件。对于 git 存储库中的 Python 文件,您可以使用如下代码:

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

我最终没有使用 find,也没有创建备份文件。

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

根据文件树的深度,这个(更短的版本)可能足以满足您的需要。

注意,这也需要二进制文件,例如。

我最终运行了这个,它是 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 还是 Git。在里面。但是要注意,它 威尔触摸二进制文件,如果你有一些。在 -type f之后使用 -iname "*.py" -or -iname "*.php",如果你只想让它触摸。Py 和。Php 文件。

更新2 : 它现在替换了行尾的所有空格(也就是制表符)

这是一个 OS X > = 10.6雪豹解决方案。

它忽略. git 和. svn 文件夹 及其内容,也不会留下备份文件。

(export LANG=C LC_CTYPE=C
find . -not \( -name .svn -prune -o -name .git -prune \) -type f -print0 | perl -0ne 'print if -T' | xargs -0 sed -Ei 's/[[:blank:]]+$//'
)

括号保留子 shell 中当前 shell 执行的 L*变量。

这里不是排除文件,而是根据文件扩展名显式列出文件的一种变体,你可以根据自己的喜好随意选择:

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:]]*$//"

两种替代方法也与 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 特定于存储库的 Solution by Mat,它使用 git grep-I选项跳过 Git 认为是二进制的文件:

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

这就是我的工作原理(Mac OS X 10.8,由 Homebrew 安装的 GNU sed) :

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/' \{} \;

删除尾随空格,用空格替换制表符,用 Unix\n替换 WindowsCRLF。

有趣的是,我必须运行这3-4次之前,所有的文件得到修复,所有的清洁 gsed指令。

这个工作得很好. . add/delete —— include 用于特定的文件类型:

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

阿克就是为这种任务而生的。

它的工作原理与 grep 类似,但是知道不要下降到. svn、 . git、 . cvs 等位置。

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

比使用 find/grep 跳过圈子要容易得多。

Ack 可以通过大多数包管理器获得(如 Ak-grep)。

它只是一个 Perl 程序,所以它也有一个单文件版本,您只需下载并运行即可。见: 安装

ex

尝试使用 前任编辑(Vim 的一部分) :

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

注意: 对于递归(bash4 & zsh) ,我们使用 一种新的球状选择(**/*.*)。

您可以在 .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: 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

从要扫描的目录运行此脚本。在 OSX 的最后,它会删除所有以 .bak结尾的文件。

或者只是:

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

这是由 Spring 框架代码样式推荐的方式。

露比:

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

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:],因为我通常不会看到垂直选项卡、表单提要和不可破坏的空格。你的测量可能会有所不同。

我使用正则表达式。4步:

  1. 在编辑器中打开根文件夹(我使用 VisualStudio 代码)。
  2. 点击左边的 Search 图标,启用正则表达式模式。
  3. 在搜索栏中输入“ + n”,在替换栏中输入“ n”。
  4. 点击“全部替换”。

这将删除所有文件中每行结尾处的所有尾随空格。你可以排除一些不符合这个需要的文件。