Reputation: 241
I have just inherited a new C++ project where plenty of files are indented with tabs while more recent ones are programmed with spaces. 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?
Upvotes: 2
Views: 1128
Reputation: 4579
Using any solution using find
one has to think about all possible filename extensions, looking at the GCC manual there are plenty of them.
Ack has a very good file selection option, just pass --cc
as parameter to only match C++ files.
So, replace all tabs in all C++ files including header files use:
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.
Upvotes: 1
Reputation: 360335
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.
The --initial
option ignores tabs which follow non blanks.
Upvotes: 3
Reputation: 1702
I have two answers. First, to answer your specific question, I'd use perl
or similar, like so:
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. This is crucial to your use case, because you don't want to replace other TABs; e.g., those that are part of some static string in the code.
Use this inside of a shell script such as:
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.
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.
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; at exactly the point in time when it affects you (i.e., 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.
Upvotes: 1