To convert tabs in a text file to spaces, you can use the expand command. To convert each tab to a single space character, use the -t 1 option.
Change Tab to use "Insert Spaces" instead of "Keep Tabs". Note you can also specify this per language if you wish to have different behavior in a specific language. Just to share that is still the same for Visual Studio 2013.
Simple replacement with sed
is okay but not the best possible solution. If there are "extra" spaces between the tabs they will still be there after substitution, so the margins will be ragged. Tabs expanded in the middle of lines will also not work correctly. In bash
, we can say instead
find . -name '*.java' ! -type d -exec bash -c 'expand -t 4 "$0" > /tmp/e && mv /tmp/e "$0"' {} \;
to apply expand
to every Java file in the current directory tree. Remove / replace the -name
argument if you're targeting some other file types. As one of the comments mentions, be very careful when removing -name
or using a weak, wildcard. You can easily clobber repository and other hidden files without intent. This is why the original answer included this:
You should always make a backup copy of the tree before trying something like this in case something goes wrong.
Try the command line tool expand
.
expand -i -t 4 input | sponge output
where
-i
is used to expand only leading tabs on each line;-t 4
means that each tab will be converted to 4 whitespace chars (8 by default).sponge
is from the moreutils
package, and avoids clearing the input file. On macOS, the package moreutils
is available via Homebrew (brew install moreutils
) or MacPorts (sudo port install moreutils
).Finally, you can use gexpand
on macOS, after installing coreutils
with Homebrew (brew install coreutils
) or MacPorts (sudo port install coreutils
).
Warning: This will break your repo.
This will corrupt binary files, including those under
svn
,.git
! Read the comments before using!
find . -iname '*.java' -type f -exec sed -i.orig 's/\t/ /g' {} +
The original file is saved as [filename].orig
.
Replace '*.java' with the file ending of the file type you are looking for. This way you can prevent accidental corruption of binary files.
Downsides:
Collecting the best comments from Gene's answer, the best solution by far, is by using sponge
from moreutils.
sudo apt-get install moreutils
# The complete one-liner:
find ./ -iname '*.java' -type f -exec bash -c 'expand -t 4 "$0" | sponge "$0"' {} \;
Explanation:
./
is recursively searching from current directory-iname
is a case insensitive match (for both *.java
and *.JAVA
likes)type -f
finds only regular files (no directories, binaries or symlinks)-exec bash -c
execute following commands in a subshell for each file name, {}
expand -t 4
expands all TABs to 4 spacessponge
soak up standard input (from expand
) and write to a file (the same one)*. NOTE: * A simple file redirection (> "$0"
) won't work here because it would overwrite the file too soon.
Advantage: All original file permissions are retained and no intermediate tmp
files are used.
Use backslash-escaped sed
.
On linux:
Replace all tabs with 1 hyphen inplace, in all *.txt files:
sed -i $'s/\t/-/g' *.txt
Replace all tabs with 1 space inplace, in all *.txt files:
sed -i $'s/\t/ /g' *.txt
Replace all tabs with 4 spaces inplace, in all *.txt files:
sed -i $'s/\t/ /g' *.txt
On a mac:
Replace all tabs with 4 spaces inplace, in all *.txt files:
sed -i '' $'s/\t/ /g' *.txt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With