0

I just stumbled upon a problem that I find surprisingly difficult. I'd like to replace all tab characters at the beginnings of lines in all *.cc and *.h files with 8 spaces. Something like:

sed  's/\t/        /g' -i  *.cc *.h

But only for the beginnings of lines. Keep in mind that sed 's/^\t/ /g' -i *.cc *.h won't do as it doesn't handle the case when the line begins with multiple tabulation characters.

How can I achieve this using sed?

Braiam
  • 1
  • 11
  • 47
  • 78
d33tah
  • 10,999
  • 13
  • 68
  • 158
  • 1
    You probably need a C beautifier. Check out this [question on Stackoverflow][1]. [1]: http://stackoverflow.com/questions/841075/best-c-code-formatter-beautifier – unxnut Jan 05 '14 at 17:59
  • Well, I'd basically like to make this particular change only. Configuring beautifier to do all the job would take a lot of time. – d33tah Jan 05 '14 at 18:00
  • In regex, the asterisk is used to denote zero or more of the preceding symbol. So, the following sed command might work, but I didn't test: `sed 's/^\t\t*/ /g' -i *.cc *.h` The ^\t\t* would denote one or more tab characters at the beginning of a line. – mti2935 Jan 05 '14 at 18:16
  • I don't think it will replace multiple tabs with multiple sequences of 8 spaces. – d33tah Jan 05 '14 at 18:17
  • OK, I understand what you're trying to do now. I think what you need is a loop that repeatedly executes the command that you originally posted `sed 's/^\t/ /g' -i *.cc *.h` until there are no longer any lines that start with `\t`. The test condition would be something like `(grep ^\t filename | wc -l)==0`. Not sure if it would have to be done with a small script, or if it's possible to do it somehow with a clever one-liner. – mti2935 Jan 06 '14 at 00:58

3 Answers3

2

You can use following command:

sed ':label s/^\(\(        \)*\)\t/\1        /; t label' -i  *.cc *.h

You can read about branching in sed here: http://www.thegeekstuff.com/2009/12/unix-sed-tutorial-6-examples-for-sed-branching-operation/

jyotesh
  • 330
  • 5
  • 17
0

Using sed

sed -r ':a s/(^ {8}*)\t/\1        /;ta'
BMW
  • 42,880
  • 12
  • 99
  • 116
0

Try using,

sed -e '/^\t/ s/\t/        /g'
Braiam
  • 1
  • 11
  • 47
  • 78
randomusername
  • 7,927
  • 23
  • 50