1833873 Members
2030 Online
110063 Solutions
New Discussion

SED help

 
SOLVED
Go to solution
Bob Luce
New Member

SED help

How can I replace a space with a pound sign but only in columns 10-20 of a large text file? For example: 's/ /#/g' will replace all occurrences, but I only want to replace occurrences in columns 10-20, but not 0-9 or 21-80.

Thanks!
10 REPLIES 10
H.Merijn Brand (procura
Honored Contributor
Solution

Re: SED help

# perl -pi -e'substr($_,10,10)=~s/ /#/g' large_file

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
baiju_3
Esteemed Contributor

Re: SED help

Hi Bob ,

Considering you can split the columns using a filed delimeter ,

example "|" (or can be any thing )


cat infile |awk -F"|" '{print $1,$2,$3}' |while read a b c;do
echo "$a `echo $b|sed 's/ /#/g'` $c"
done

Assuming the change need will be in the second column of awk o/p.

I think you can manipulate this loop and achieve what you need.


Thanks,
-BL.



Good things Just Got better (Plz,not stolen from advertisement -:) )
David DiBiase
Frequent Advisor

Re: SED help

I didnt have time to build an input file to test this but, try the following:
Note: the first paren grp has 9 chars so it is checking for a space in column 10, thes next line addresses a space in column 11 up to column 20.


sed -e 's/\(.........\) \(.*\)/\1#\2/
s/\(..........\) \(.*\)/\1#\2/
s/\(...........\) \(.*\)/\1#\2/
s/\(............\) \(.*\)/\1#\2/
s/\(.............\) \(.*\)/\1#\2/
s/\(..............\) \(.*\)/\1#\2/
s/\(...............\) \(.*\)/\1#\2/
s/\(................\) \(.*\)/\1#\2/
s/\(.................\) \(.*\)/\1#\2/
s/\(..................\) \(.*\)/\1#\2/
s/\(...................\) \(.*\)/\1#\2/' output
Rodney Hills
Honored Contributor

Re: SED help

I don't sed can do that, but perl can-

perl -p -e 'substr($_,10,10)=~s/ /#/g' yourfile

HTH

-- Rod Hills
There be dragons...
H.Merijn Brand (procura
Honored Contributor

Re: SED help

Rodney, what did that add to my answer?

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
David DiBiase
Frequent Advisor

Re: SED help

one of these days I need to push aside my C and ksh stuff to learn more about perl :-)
Rodney Hills
Honored Contributor

Re: SED help

Procura,

I didn't see your answer when I entered mine...

Rod H
There be dragons...
Bob Luce
New Member

Re: SED help

The perl command worked very well, thanks. Unfortunately I forgot to mention one other part of my requirement - I am only looking for "embedded" spaces in my field, not "trailing" spaces. For example,
"ABC A " should convert to
"ABC###A ", not to
"ABC###A###".
H.Merijn Brand (procura
Honored Contributor

Re: SED help

# perl -pi -e'substr($_,10,10)=~s/( +)(?=\S)/"#"x length$1/ge' large_file

I think, though by the time you want to go more complex, it might be better to write a real script

There are two extra problems here:

- if lines are shorter than 20 characters, you will get a warning like

substr outside of string at -e line 1, <> line 1.

- if you only check 10 chracters at offset 10, you don't look ahead to see if there are non-blanks after that character, and your defenition is not clear enough about when to change (IMHO)

but you can safeguard that

First decide, what to do if the line is shorter than 20 characters.
Then decide if the trailing non-space should be within the changed block, or if it is allowed in the trailing line

IF you have NO trailing # signs in your document, the solution is even simpler

# perl -pi -e'substr($_,10,10)=~y/ /#/;s/(#+)$/" "x length$1/e' large_file

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
Rodney Hills
Honored Contributor

Re: SED help

How about this perl one liner-
perl -p -e 'substr($_,10,10)=~s/ (?! *$)/#/g' largefile

By using the (?! ) construct, the pattern match will replace spaces with # unless the rest of the text is all blanks within positions 10-20.

HTH

-- Rod Hills
There be dragons...