Replace blanks with | (pipe)

Hello,

I'm trying to replace the first x number of spaces in a line with a |. Right now I'm using a very inefficient syntax to accomplish the task and was looking to simplify it.

I have several cases were the pipes need to replace just the first space on the line, which I did a simple replace. I am doing this while reading each line of a file that I'm cat'ing.

v_sec=`echo $line | sed 's/ /|/'`

The ugly code comes in when I need to replace the first 11 spaces with pipes and ended up doing this:

		v_bar1=`echo $line | sed 's/ /|/'`
			v_bar2=`echo $v_bar1 | sed 's/ /|/'`
			v_bar3=`echo $v_bar2 | sed 's/ /|/'`
			v_bar4=`echo $v_bar3 | sed 's/ /|/'`
			v_bar5=`echo $v_bar4 | sed 's/ /|/'`
			v_bar6=`echo $v_bar5 | sed 's/ /|/'`
			v_bar7=`echo $v_bar6 | sed 's/ /|/'`
			v_bar8=`echo $v_bar7 | sed 's/ /|/'`
			v_bar9=`echo $v_bar8 | sed 's/ /|/'`
			v_bar10=`echo $v_bar9 | sed 's/ /|/'`
			v_bar_final=`echo $v_bar10 | sed 's/ /|/'`

Any suggestions to simplify would be appreciated. :b:

hi,
Do you mean 11 spaces in the beginning?

sed -s 's/^    */|/' input 

Here im finding for 4 or more spaces to substitute.you can increase it if your file has 4 spaces or more use {n} option.

sed -s 's/^ \{11\}/|/' input

Input:

           
test           make
           check           this

output:

|
test           make
|check           this

Try:

sed ':a;s/^\(|*\) /\1|/;ta'

or

sed -e :a -e 's/^\(|*\) /\1|/;ta'
$ echo "           xxx xx xxxxx  yyyy" | sed ':a;s/^\(|*\) /\1|/;ta'
|||||||||||xxx xx xxxxx  yyyy

My apologizes, I should have been more specific. The data looks like this:

Dataset1 Dataset2 Dataset3 etc etc etc A B C D E F G blah blah blah

Required output would then be:

Dataset1|Dataset2|Dataset3|etc|etc|etc|A|B|C|D|E|F G blah blah blah

$ ruby -ane 'print "#{$F[0..11].join("|")} #{$F[12..-1].join(" ")}\n"' file
Dataset1|Dataset2|Dataset3|etc|etc|etc|A|B|C|D|E|F G blah blah blah

I'm not comfortable using ruby, as this is the first time I have heard of it.

awk '{for(i=1;i<=NF;i++){s=(i<12)?"|":FS;if(i==NF)s=RS;printf $i s}}' file
1 Like

It works exactly as I need. Thanks!

Yes, 11 is a big number for sed!

You might have done this:

sed '
  s/ /|/
  s/ /|/
  s/ /|/
  s/ /|/
  s/ /|/
  s/ /|/
  s/ /|/
  s/ /|/
  s/ /|/
  s/ /|/
  s/ /|/
 '

and there is this, but it falls short at 9 (Is there a newer sed with more \(\) tags? They changed regex, why not this and the silly 2 digit \{\} limit?):

sed '
  s/^\([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\) \([^ ]*\) /\1|\2|\3|\4|\5|\6|\7|\8|\9|/
  s/^\([^ ]*\) \([^ ]*\) /\1|\2|/
 '

Sadly, even ksh seems less limited:

#!/usr/bin/ksh

fix_line(){

 i = 0

 while (( $(( i  += 1 )) <= 11 ))
 do
   echo "$1|"
   shift
 done

 echo "$*"
}

while read ln
do
 fix_ln $ln
done

GNU sed:

sed 's/ /|/g;s/|/ /12g' infile
1 Like

If 12g, why not g11 ? Did the GNU miss symmetry? Yes! We should tune it up!

 
$ echo '1234567890' |local/bin/sed 's/[0-9]/x/3g'
12xxxxxxxx
$ echo '1234567890' |local/bin/sed 's/[0-9]/x/g3'
12xxxxxxxx
$

using Perl:-

perl -wlane 'print join("|",@F[0..11])," ",join(" ",@F[12..$#F])'  infile.txt

;);):wink: