【问题标题】:Is there a way to change all tabs to spaces for all files in a directory using bash?有没有办法使用 bash 将目录中所有文件的所有选项卡更改为空格?
【发布时间】:2019-11-07 11:26:25
【问题描述】:

我刚刚继承了一个新的 C++ 项目,其中大量文件使用制表符缩进,而最近的文件则使用空格进行编程。现在我想将它们全部更改为仅使用空格。与其进入每个文件并使用 EMac 的自动缩进功能,有没有更有效的方法可以使用 bash 来实现?

【问题讨论】:

  • OFC 有(有);例如,您可以为每个 + sed 脚本编写一个...到目前为止您尝试了什么?
  • 文件都是在一个目录下还是在多个子目录下?
  • @cyrus 文件位于多个目录/子目录中
  • @danlor 我对使用sed 持保留态度,因为我找到了here 的答案

标签: bash tabs spaces


【解决方案1】:

这将递归遍历项目文件并将制表符展开为空格。由于我确定您使用的是源代码管理,因此如果出现问题,您可以轻松恢复。

find /path/to/project -type f -name '*.cpp' -exec expand --initial {} +

默认为 8 个空格,但您可以使用 --tabs=4 或任何您想要的值。

--initial 选项会忽略非空格后面的制表符。

【讨论】:

  • 非常好。和unexpand 将空格转换为制表符。
【解决方案2】:

我有两个答案。首先,要回答您的具体问题,我会使用perl 或类似名称,如下所示:

replace-tab-indents.pl

#!/usr/bin/perl

while ($line = <STDIN>) {
    while ($line =~ /^ *\t/) {
        $line =~ s/^( *)\t/$1    /;
    }

    print(STDOUT $line);
}

只处理行首的制表符。这对您的用例至关重要,因为您不想替换其他 TAB;例如,那些是代码中某些静态字符串的一部分。

在 shell 脚本中使用它,例如:

for FILE in `find . -name *.cpp`; do
    mv -i "$FILE" "$FILE.bak"
    cat "$FILE.bak" | replace-tab-indents.pl > "$FILE"
done

find 上使用-name 选项将您限制为仅使用源文件,从而避免您正确担心与替换所有文件中的所有制表符相关的问题——在许多非源文件中, “TAB”字节对于构成该文件的数据至关重要。

我的第二个答案是随时更改它们,而不是一次全部更改。

通过这种方式,您可以使用 emacs(或 vim,或任何现代编辑器,真的),这将是一种更加经过测试、久经考验、可靠的方法。

这些文件可以使用 TAB 很好地编译,因此在您需要编辑给定文件之前,TAB 缩进的存在不会影响您;在它影响您的确切时间点(即您第一次编辑它时),您可以使用您的编辑器重新缩进空格。简而言之,我的建议是即时/随用随用,而不是一次性完成。

换句话说,编译器不关心缩进,只有你关心;您唯一需要关心的是您实际编辑给定源文件的时间;因此,重新缩进源文件大量并没有经验上的好处。

【讨论】:

    【解决方案3】:

    使用任何使用find 的解决方案都必须考虑所有可能的文件扩展名,看看GCC manual 有很多。

    Ack 有一个很好的文件选择选项,只需将--cc 作为参数传递以仅匹配 C++ 文件。

    因此,替换所有 C++ 文件中的所有选项卡,包括头文件使用:

    ack --cpp -l --print0 . | xargs -0 -n1 sed -i -e 's/\t/    /' 
    

    ack 将递归查找当前目录中的所有 C++ 文件,并仅将文件名传递给sed,这会将所有制表符替换为四个空格。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-16
      • 2015-10-25
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      • 2017-06-02
      • 2010-11-18
      • 2012-05-11
      相关资源
      最近更新 更多