如何将制表符转换为一个目录的每个文件中的空格(可能递归)?

此外,是否有一种方法来设置每个制表符的空格数?


当前回答

将目录下的所有Java文件递归转换为4个空格而不是制表符:

find . -type f -name *.java -exec bash -c 'expand -t 4 {} > /tmp/stuff;mv /tmp/stuff {}' \;

其他回答

使用vim-way:

$ ex +'bufdo retab' -cxa **/*.*

做备份!在执行上述命令之前,因为它可能损坏您的二进制文件。 要使用globstar(**)进行递归,请通过shop -s globstar激活。 指定特定的文件类型,例如:**/*.c。

修改制表符,添加+'set ts=2'。

然而,缺点是它可以替换字符串中的制表符。

因此,为了更好的解决方案(使用代换法),尝试:

$ ex -s +'bufdo %s/^\t\+/  /ge' -cxa **/*.*

或者使用ex编辑器+扩展实用程序:

$ ex -s +'bufdo!%!expand -t2' -cxa **/*.*

有关尾随空格,请参见:如何为多个文件删除尾随空格?


你可以在你的.bash_profile中添加以下函数:

# Convert tabs to spaces.
# Usage: retab *.*
# See: https://stackoverflow.com/q/11094383/55075
retab() {
  ex +'set ts=2' +'bufdo retab' -cxa $*
}

尝试命令行工具expand。

expand -i -t 4 input | sponge output

在哪里

-i用于只展开每行的前导制表符; -t 4表示每个制表符将转换为4个空格字符(默认为8个)。 Sponge来自moreutils包,避免清除输入文件。在macOS上,moreutils包可以通过Homebrew (brew install moreutils)或MacPorts (sudo port install moreutils)获得。

最后,在使用Homebrew (brew install coreutils)或MacPorts (sudo port install coreutils)安装coreutils之后,可以在macOS上使用gexpand。

警告:这会破坏你的回购。 这将破坏二进制文件,包括那些在svn, .git!使用前请阅读评论!

找到。-iname '*.java' -type f -exec sed -i。/\t/ /g' {} +

原始文件保存为[filename]. trans。

将'*.java'替换为您正在寻找的文件类型的文件结尾。这样可以防止二进制文件的意外损坏。

缺点:

将替换文件中的所有制表符。 如果在这个目录中有一个5GB的SQL转储,将花费很长时间。

从Gene的回答中收集最好的评论,到目前为止最好的解决方案是使用moreutils的海绵。

sudo apt-get install moreutils
# The complete one-liner:
find ./ -iname '*.java' -type f -exec bash -c 'expand -t 4 "$0" | sponge "$0"' {} \;

解释:

./从当前目录递归搜索 -iname是不区分大小写的匹配(对*.java和*.java都适用) Type -f只查找常规文件(没有目录、二进制文件或符号链接) -exec bash -c在子shell中为每个文件名执行以下命令,{} expand -t 4将所有tab扩展为4个空格 海绵吸收标准输入(从扩展)并写入文件(同一文件)*。

注意:*一个简单的文件重定向(> "$0")在这里不能工作,因为它会很快覆盖文件。

优点:保留所有原始文件权限,不使用中间的tmp文件。

简单地用sed替换是可以的,但不是最好的解决方案。如果制表符之间有“额外的”空格,替换后它们仍然在那里,因此页边距将是粗糙的。在行中间展开的制表符也不能正常工作。在bash中,我们可以说相反

find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;

将展开应用到当前目录树中的每个Java文件。如果目标是其他文件类型,则删除/替换name参数。正如其中一条评论提到的,在删除name或使用弱通配符时要非常小心。你可以很容易地破坏存储库和其他隐藏的文件。这就是为什么最初的答案是这样的:

在尝试这样做之前,您应该始终对树进行备份,以防出现错误。