- Replace whitespaces with tabs in linux
- Expand — Convert Tabs to Spaces on Linux Command Line
- Convert Tabs to Spaces in a File
- Replace Tabs with x Number of Spaces
- Convert Only Leading Tabs to Spaces
- Conclusion
- Resources and Links
- Convert Tabs to Spaces in Linux Terminal With Expand Command
- Using expand command to convert tabs into spaces in Linux command line
- Check if your text file has tabs
- Convert tabs into spaces with expand command
- Reduce the number of spaces
- Convert only leading tabs into spaces
- Convert tabs into spaces and save it to the original file
- Convert tabs into spaces in all the matching files in a directory
Replace whitespaces with tabs in linux
Woah, never knew expand/unexpand existed. I was trying to do the opposite and expand was perfect rather than having to mess around with tr or sed .
So cool that these are standard. I love the UNIX philosophy. Would be nice if it could do in place though.
I don’t think unexpand will work here.. it only convert the leading spaces and only with two or more spaces.. see here:lists.gnu.org/archive/html/bug-textutils/2001-01/msg00025.html
Just a caution — unexpand will not convert a single space into a tab. If you need to blindly convert all runs of 0x20 characters into a single tab, you need a different tool.
I think you can try with awk
sed 's/[:blank:]+/,/g' thefile.txt > the_modified_copy.txt
tr -s '\t' < thefile.txt | tr '\t' ' ' >the_modified_copy.txt
or a simplified version of the tr solution sugested by Sam Bisbee
In your sed example, best practices dictate that you use tr to replace single characters over sed for efficiency/speed reasons. Also, tr example is much easier this way: tr ‘ ‘ \\t < someFile >someFile
Of course, tr has better performance than sed, but the main reason I have for loving Unix is that there’re many ways to do something. If you plan to do this substitution many times you will search a solution with a good performance, but if you are going to do it only once, you will serach for a solution wich involves a command that make you feel confortable.
arg. I had to use trial and error to make the sed work. I have no idea why I had to escape the plus sign like this: ls -l | sed «s/ \+/ /g»
With awk -v OFS=»\t» ‘$1=$1’ file1 I noticed that if you have a line beginning with number 0 (e.g. 0 1 2 ), then the line will be ommitted from the result.
@Jess You found «correct default syntax» regex. By default sed treat single (unescaped) plus sign as simple character. The same is true for some other characters like ‘?’, . You can find more info here: gnu.org/software/sed/manual/html_node/… . Similar syntax details can be found here (note that this is man for grep, not sed): gnu.org/software/grep/manual/grep.html#Basic-vs-Extended .
Using Perl:
Had a similar problem with replace consecutive spaces with a single tab. Perl worked worked with only the addition of a ‘+’ to the regexp.
Though, of course, I wanted to do the opposite: convert tabs to two spaces: perl -p -i -e ‘s/\t/ /g’ *.java
better tr command:
This will clean up the output of say, unzip -l , for further processing with grep, cut, etc.
unzip -l some-jars-and-textfiles.zip | tr [:blank:] \\t | cut -f 5 | grep jar
Example command for converting each .js file under the current dir to tabs (only leading spaces are converted):
find . -name "*.js" -exec bash -c 'unexpand -t 4 --first-only "$0" > /tmp/totabbuff && mv /tmp/totabbuff "$0"' <> \;
Download and run the following script to recursively convert soft tabs to hard tabs in plain text files.
Place and execute the script from inside the folder which contains the plain text files.
#!/bin/bash find . -type f -and -not -path './.git/*' -exec grep -Iq . <> \; -and -print | while read -r file; do < echo "Converting. "$file""; data=$(unexpand --first-only -t 4 "$file"); rm "$file"; echo "$data" >"$file"; >; done;
This will replace consecutive spaces with one space (but not tab).
This will replace consecutive spaces with a tab.
You can also use astyle . I found it quite useful and it has several options too:
Tab and Bracket Options: If no indentation option is set, the default option of 4 spaces will be used. Equivalent to -s4 --indent=spaces=4. If no brackets option is set, the brackets will not be changed. --indent=spaces, --indent=spaces=#, -s, -s# Indent using # spaces per indent. Between 1 to 20. Not specifying # will result in a default of 4 spaces per indent. --indent=tab, --indent=tab=#, -t, -t# Indent using tab characters, assuming that each tab is # spaces long. Between 1 and 20. Not specifying # will result in a default assumption of 4 spaces per tab.`
If you are talking about replacing all consecutive spaces on a line with a tab then tr -s ‘[:blank:]’ ‘\t’ .
[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda Device Start /dev/sda1 2048 /dev/sda2 411648 /dev/sda3 2508800 /dev/sda4 10639360 /dev/sda5 75307008 /dev/sda6 96278528 /dev/sda7 115809778 [root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda | tr -s '[:blank:]' '\t' Device Start /dev/sda1 2048 /dev/sda2 411648 /dev/sda3 2508800 /dev/sda4 10639360 /dev/sda5 75307008 /dev/sda6 96278528 /dev/sda7 115809778
If you are talking about replacing all whitespace (e.g. space, tab, newline, etc.) then tr -s ‘[:space:]’ .
[root@sysresccd /run/archiso/img_dev]# sfdisk -l -q -o Device,Start /dev/sda | tr -s '[:space:]' '\t' Device Start /dev/sda1 2048 /dev/sda2 411648 /dev/sda3 2508800 /dev/sda4 10639360 /dev/sda5 75307008 /dev/sda6 96278528 /dev/sda7 115809778
If you are talking about fixing a tab-damaged file then use expand and unexpand as mentioned in other answers.
Expand — Convert Tabs to Spaces on Linux Command Line
Programmers have been arguing over the use of spaces versus tabs forever. It was hysterically depicted in the HBO hit series Silicon Valley. If you are on the «spaces» side of that argument, you will really enjoy this read. In this tutorial we are going to discuss a simple way to convert tabs into spaces using the expand command.
If you are «team tabs» maybe you will enjoy the unexpand command, which converts spaces to tabs.
The expand command is part of the GNU Core Utilities, which means it is available on just about any Linux system. It’s main function is to convert tabs to spaces in a file. It has a few simple options, but like most of the core utils, it does one job really well.
Convert Tabs to Spaces in a File
Below we have some code taken from the «How to Make a Countdown Timer in Bash» article.
If we use the cat command with the -T option (Show tabs as ^I) we can see that this file is indented using tabs. This would make Richard Hendricks very happy!
[[email protected] ~]$ cat -T countdown.sh #!/bin/bash hour=0 min=0 sec=10 ^Iwhile [ $hour -ge 0 ]; do ^I^I while [ $min -ge 0 ]; do ^I^I^I while [ $sec -ge 0 ]; do ^I^I^I^I echo -ne "$hour:$min:$sec\033[0K\r" ^I^I^I^I let "sec=sec-1" ^I^I^I^I sleep 1 ^I^I^I done ^I^I^I sec=59 ^I^I^I let "min=min-1" ^I^I done ^I^I min=59 ^I^I let "hour=hour-1" ^I done
However, some people prefer spaces. This is were the expand command comes in handy. It allows you to easily convert all of the tabs in this file to spaces. Simply pass the filename as an argument to the expand command like so:
This will print the newly formatted file to standard output (STDOUT). To save it to a new file, simply redirect it to a file.
[sav[email protected] ~]$ expand countdown.sh > space-formatted-countdown.sh
Now we can test it again with the cat command.
[[email protected] ~]$ cat -T space-formatted-countdown.sh #!/bin/bash hour=0 min=0 sec=10 while [ $hour -ge 0 ]; do while [ $min -ge 0 ]; do while [ $sec -ge 0 ]; do echo -ne "$hour:$min:$sec\033[0K\r" let "sec=sec-1" sleep 1 done sec=59 let "min=min-1" done min=59 let "hour=hour-1" done
Here we can see that all the tabs have been converted to spaces!
Replace Tabs with x Number of Spaces
By default the expand utility will replace a tab with eight spaces. You can set the number of spaces you prefer by using the -t (—tabs=N) option. In the example below, we first replace all tabs with four spaces, then with two spaces.
Convert Only Leading Tabs to Spaces
Another feature of the expand utility is the -i (—initial) option. This conveniently allows you to convert only leading tabs in the file.
[[email protected] ~]$ cat -T test.txt This^Iis^Itab^Iseperated ^Ithis follows a tab ^Ithis follows a tab and ends with one^I This line has a tab here^Iand two here^I This line has a tab here^Iand a space and tab ^I^I ^I^I [[email protected] ~]$ expand -i test.txt > new.txt [[email protected] ~]$ cat -T new.txt This^Iis^Itab^Iseperated this follows a tab this follows a tab and ends with one^I This line has a tab here^Iand two here^I This line has a tab here^Iand a space and tab ^I^I ^I^I
As you can see, using expand -i only converted the leading tabs into spaces. Any tab following a non-blank is left intact.
Conclusion
The expand command is a niche utility but can be very useful. Of course there are many other ways to do replace tabs with spaces (sed?). However, writing a sed command for this is much more effort than using expand.
An interesting tidbit is that the GNU Core Utilities package also provides a unexpand command that allows you to convert spaces to tabs. We will discuss that in a future article.
Resources and Links
Convert Tabs to Spaces in Linux Terminal With Expand Command
This tutorial teaches you to convert the tabs into spaces in Linux command line from the programming perspective.
The debate over the use of tabs and spaces in the programming is a never ending one.
While you may prefer using tabs all the time, chances are that your coding guideline suggest using spaces.
But if you have already used tabs everywhere into your program and you need to convert those tabs into spaces so that the reviewer allows your code, you are at the right place.
In this tutorial, I’ll show you how to convert the tabs into spaces in a text file in Linux command line.
Using expand command to convert tabs into spaces in Linux command line
I am using this sample text file which is a simple C++ program for checking odd and even number. This is the content of the file:
You can download this file from here if you want to practice the command while following this tutorial.
Check if your text file has tabs
There are several ways of doing it. The simplest method I find is by using the cat command.
You can use the cat command with option -T and will display all the tabs as ^I on the screen (stdout).
You can see the location of the tabs in the file.
#include using namespace std; int main() < ^Iint n; ^Icout > n; ^I ^Iif (n%2 == 0) < ^I^Icout^Ielse ^I^Icout
Convert tabs into spaces with expand command
If you use expand command on a file, it will convert all the tabs into a block of 8 spaces and will display the output on the screen.
But that’s not very convenient, is it? You will hardly see the changes here. A better idea would be to save the output to another file.
expand tab_file > space_file
Now if you see the file using the cat command, you won’t find any tabs anymore.
Reduce the number of spaces
As I mentioned in the previous section, by default, a tab is equal to 8 spaces. That would look super weird if your code has such huge indentation.
The good thing is that you can change the default space size with the -t option.
For example, if you have to change each tab into 2 spaces, you can use the expand command like this:
expand -t2 tab_file > space_file
Convert only leading tabs into spaces
Often in the programs, you would only want to convert the leading tabs i.e. the tabs at the beginning of the line. You don’t want to touch the tabs in between the lines that are actually part of the code.
Expand provides this option as well. If you want to only convert the leading tabs into spaces, use the –i option.
If we continue the previous example, here is what the command would look like:
expand -t2 -i tab_file > space_file
Convert tabs into spaces and save it to the original file
In all the above examples, you have saved the converted file into a new file. But if your aim is to clean your code by convert the tabs into spaces of the existing program files, you would want the output to be saved in the original file itself.
To do that, you can use the sponge command. Sponge ‘soaks up’ the entire standard input before writing it to output. This is extremely useful when you are trying to change and save the same file.
Now, the sponge command may not be available on your system. You’ll have to install the moreutils package. It should be available
On Ubuntu/Debian based distributions, you can use this command to install moreutils:
sudo apt install moreutils
Once installed, you can use it in the following function:
expand -t2 -i tab_file | sponge tab_file
Convert tabs into spaces in all the matching files in a directory
Till now whatever you learned was applicable to a single file. But if you have a project that has several program files and you want to convert the tabs into spaces in all of them, you’ll have to be a bit smarter here.
What we have learned so far can be combined with the magnificent find and exec commands.
find . -name '*.cpp' -type f -exec bash -c 'expand -t 4 "$0" | sponge "$0"' <> \;
The above command finds all the files ending with extension cpp, pass these files to the expand command and the expand command writes the output to the original files with the help of sponge command.
You might think using sed command would have been easier at this point but that’s entirely your choice.