Elite Mx
Elite Mx

Reputation: 141

N-Insert In Sed

How would I replace the first 150 characters of every line with spaces using sed. I don't want to bring out the big guns (Python, Perl, etc) and it seems like sed is pretty powerful in itself (some people have written the dc calculator in it for example). A related problem is inserting 150 spaces in front of every line.

s/^.\{50\}/?????/

That matches the first 50 characters but then what? I can't do output

s/^.\{50\}/ \{50\}/

One could use readline to simulate 150 presses (alt+150, ) but that's lame.

Upvotes: 1

Views: 273

Answers (4)

potong
potong

Reputation: 58381

This might work for you:

sed ':a;/^ \{150\}/!{s/[^ ]/ /;ta}' file

This will replace the first 150 characters of a line with spaces. However if the line is shorter than 150 it replace it all with spaces but retain the original length.

This solution replaces the first 150 characters with spaces or increases the line to 150 spaces long:

sed ':a;/^ \{150\}/!{s/[^ ]/ /;ta;s/^/ /;ba}' file

And this replaces the first 150 characters of a line with spaces but leaves lines shorter untouched:

sed '/.\{150\}/!b:a;/^ \{150\}/!{s/[^ ]/ /;ta}' file

Upvotes: 1

Potatoswatter
Potatoswatter

Reputation: 137780

Use the hold space.

/^.\{150\}/ {;# simply echo lines shorter than 150 chars
    h;# make a backup
    s/^.\{150\}\(.*\)/\1/;# strip 150 characters
    x;# swap backup in and remainder out
    s/^\(.\{150\}\).*/\1/;# only keep 150 characters
    s/./ /g;# replace every character with a space
    G;# append newline + remainder to spaces
    s/\n//;# strip pesky newline
};

Alternately, you could code a loop (somewhat shorter code):

s/^.\{150\}/x/;# strip 150 characters & mark beginning of line
t l
# if first substitution matched, then loop
d; # else abort and go to next input line
:l
# begin loop
s/^/ /;# insert a space
/^ \{150\}x/!t l
# if line doesn't begin with 150 spaces, loop
s/x//;# strip beginning marker

However, I don't think you can use a loop without sed -f, or finding some other way to escape newlines. Label names seem to run to the end of the line, right through a ;.

Upvotes: 3

ghostdog74
ghostdog74

Reputation: 342333

The logic is to iterate the file, print 150 spaces, and then print the rest of the line from 151 till the end using "substringing". eg for first 10 chars.

$ more file
1234567890abc
0987654321def
$ awk '{printf "%10s%s\n", " ",substr($0,11)}' file
          abc
          def

this is much simpler than crafting regex.

Bash:

while read -r line
do
    printf "%10s%s\n" " " "${line:10}"
done <"file"

Upvotes: 1

dubiousjim
dubiousjim

Reputation: 4802

Basically you want to do this:

sed -r "s/^.{150}/$(giveme150spaces)/"

The question is just what's the most elegant way to programatically get 150 spaces. A variety of techniques are discussed here: Bash Hacker's Wiki. The simplest is to to use printf '%150s', like this:

sed -r "s/^.{150}/$(printf '%150s')/"

Upvotes: 2

Related Questions