简体   繁体   English

有没有办法使用bash将所有选项卡更改为目录中所有文件的空格?

[英]Is there a way to change all tabs to spaces for all files in a directory using bash?

I have just inherited a new C++ project where plenty of files are indented with tabs while more recent ones are programmed with spaces. 我刚刚继承了一个新的C ++项目,其中大量文件使用制表符缩进,而最近的文件则使用空格进行编程。 Now I want to change them all to using spaces only. 现在我想将它们全部更改为仅使用空格。 Instead of going into every files and using EMacs auto-indent function, is there a more efficient way I could achieve it with bash? 而不是进入每个文件并使用EMacs自动缩进功能,是否有更有效的方式我可以用bash实现它?

I have two answers. 我有两个答案。 First, to answer your specific question, I'd use perl or similar, like so: 首先,为了回答你的具体问题,我会使用perl或类似的,如下:

replace-tab-indents.pl replace-tab-indents.pl

#!/usr/bin/perl

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

    print(STDOUT $line);
}

This deals with only TABs at the start of the line . 这只涉及行首的TAB This is crucial to your use case, because you don't want to replace other TABs; 这对您的用例至关重要,因为您不想替换其他TAB; eg, those that are part of some static string in the code. 例如,那些是代码中某些静态字符串的一部分。

Use this inside of a shell script such as: 在shell脚本中使用此内容,例如:

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

The use of the -name option on find limits you to just your source files, avoiding the problems that you correctly are wary of related to replacing all TABs in all files -- in many non-source files, the "TAB" byte is crucial to the data that comprises that file. -name上使用-name选项find限制您只对源文件进行限制,从而避免与您更换所有文件中的所有TAB相关的问题 - 在许多非源文件中,“TAB”字节至关重要到包含该文件的数据。

My second answer is to just change them as you go, instead of all at once. 我的第二个答案就是随时改变它们,而不是一次性改变它们。

This way you can employ emacs (or vim, or any modern editor, really), which will be a more tested, tried-and-true, robust approach. 通过这种方式,您可以使用emacs(或vim,或者任何现代编辑器),这将是一种经过测试,经过实践验证的强大方法。

The files compile just fine with TABs, so until you need to edit a given file, the presence of the TAB indentation does not affect you; 使用TAB编译文件很好,因此在您需要编辑给定文件之前,TAB缩进的存在不会影响您; at exactly the point in time when it affects you (ie, the first time you edit it), you can use your editor to re-indent with spaces. 在它影响到您的时间点(即第一次编辑它)时,您可以使用编辑器重新缩进空格。 In short, my advice here is to accomplish this just-in-time / as-you-go, not all-at-once. 简而言之,我在这里的建议是及时完成这项任务,而不是一次性完成。

Said differently, the compiler doesn't care about the indentation, only you do; 换句话说,编译器并不关心缩进,只有你这样做; and the only time you will care is when you actually edit a given source file; 而你唯一需要关心的是你实际编辑给定的源文件; so, there is no empirical benefit from re-indenting your source files en mass . 所以,有一个从重新缩进源文件的连接质量没有经验的好处。

Using any solution using find one has to think about all possible filename extensions, looking at the GCC manual there are plenty of them. 使用任何使用find解决方案必须考虑所有可能的文件扩展名,查看GCC手册有很多。

Ack has a very good file selection option, just pass --cc as parameter to only match C++ files. Ack有一个非常好的文件选择选项,只需传递--cc作为参数,只匹配C ++文件。

So, replace all tabs in all C++ files including header files use: 因此,替换所有C ++文件中的所有选项卡,包括头文件使用:

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

ack will find all C++ files recursively in the current directory and pass only the file names to sed , which replaces all tabs with four spaces. ack将在当前目录中递归地查找所有C ++文件,并仅将文件名传递给sed ,这将用四个空格替换所有选项卡。

This will traverse the project files recursively and expand the tabs to spaces. 这将递归遍历项目文件并将选项卡展开到空格。 Since I'm sure you're using source control, you can easily revert if something goes awry. 由于我确定您正在使用源代码管理,因此如果出现问题,您可以轻松恢复。

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

The default is eight spaces, but you can use --tabs=4 or whatever value you want. 默认值为八个空格,但您可以使用--tabs=4或任何您想要的值。

The --initial option ignores tabs which follow non blanks. --initial选项忽略非空格的制表符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM