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!
[savona@putor ~]$ 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:
[savona@putor ~]$ expand countdown.sh
This will print the newly formatted file to standard output (STDOUT). To save it to a new file, simply redirect it to a file.
[savona@putor ~]$ expand countdown.sh > space-formatted-countdown.sh
Now we can test it again with the cat command.
[savona@putor ~]$ 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.
[savona@putor ~]$ 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 [savona@putor ~]$ expand -i test.txt > new.txt [savona@putor ~]$ 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.
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
This site uses Akismet to reduce spam. Learn how your comment data is processed.