Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace each leading tab by four spaces, recursively for every file

What is the easiest way of achieving this using common tools in Linux?

I have looked at:

  1. sed, but don't know enough about how to count the matched leading tabs in an expression like sed -i 's/^[\t]*/<what-to-put-here?>/g myFile.c.
  2. astyle, but can't figure out how to tell it to just reindent and NOT format
  3. indent, same problem as astyle
  4. expand, but it also replaces non-leading tabs and I have to handle the inplace replacement myself which is error prone.

I was just looking for a quick and easy solution that I can plug into a find -type f -name "*.c" -exec '<tabs-to-spaces-cmd> {}' \;

like image 282
Alin Tomescu Avatar asked Aug 23 '14 20:08

Alin Tomescu


People also ask

How do I replace a tab with 4 spaces in vim?

in vim you can do this: # first in . vimrc set up :set expandtab :set tabstop=4 # or you can do this :set tabstop=4 shiftwidth=4 expandtab # then in the py file in command mode, run :retab! :set noet|retab!

How do I change all tabs with spaces?

Instead of changing tabs to spaces one by one, the Word's Find and Replace function is commonly used to convert tabs to spaces. Step 3: Enter a space character (press space button on your keyboard) in the Replace With field; Step 4: Click Replace All.


2 Answers

You should really use expand since it is developed only to do that. From its documentation:

-i, --initial
   do not convert tabs after non blanks

So the command for a single file would be:

expand -i -t 4 input > output

In order to use it with multiple file you will need a trick:

expand_f () {
  expand -i -t 4 "$1" > "$1.tmp"
  mv "$1.tmp" "$1"
}

export -f expand_f
find -type f -iname '*.c' -exec bash -c 'expand_f {}' \;

This is used to prevent expand to write on the file while it is still processing it, and to avoid redirecting the stdout of find instead of the one of expand.

like image 63
enrico.bacis Avatar answered Nov 15 '22 03:11

enrico.bacis


This might work for you (GNU sed):

sed -ri ':a;s/^( *)\t/\1    /;ta' file
like image 24
potong Avatar answered Nov 15 '22 05:11

potong