Link to home
Start Free TrialLog in
Avatar of Eric_1969
Eric_1969

asked on

Unix sed

Hello, everyone, I'm new to this board, and I hope I'm posting to the right area.

I'm working with sed, and I'm wondering if there's a way to copy a specific part of a text file to another part of the file.
For example, if I have a one-line text file like this...

This is a test

Can I use sed somehow to make it look like this...

This is a test     This is a test

I'm hoping there's a way to specify exact columns to tell sed to copy columns 1-10 to columns 30-40.

Any help would be greatly appreciated!
Avatar of heskyttberg
heskyttberg

Hi!

I don't think sed is what you are looking for here.
Sed is a text editor so to speak nothing else.

You should look into awk or gawk.

With this you could make such scripts to copy columns cause awk is almost a text based database handler.

Regards
/Hans - Erik Skyttberg
ASKER CERTIFIED SOLUTION
Avatar of jimbb
jimbb

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Try This,

excute this script with 4 parameters in your case put 1 10 30 40


#!/bin/ksh
cat testfile |awk -v s1=$1 -v e1=$2 -v s2=$3 -v e2=$4 '{
if((NF<e1)||(s2<e2)||((e1-s1)!=(e2-s2))||(NF<s2))
{
        add1=s2-NF
        printf $0;
        for(i=1;i<=add1;i++)
        printf "        ";
        for(i=s1;i<=e1;i++)
        printf $(i)" ";
}
else
{
        print "Error"
}
}'
The silly sed thing to do is something like:
sed -e 's/\(.\{10\}\)\(.\{20\}\)\(.\{0,\}\)/\1\2\1\3/' file
where the \{0,\} is a sligtly more portable \* or even \+.
Lines that simply don't match (ie have 30+ character columns) will be emitted "as-is".

-- Glenn
grrr. "(ie have 30+ character columns)" should read "(ie don't have 30+ character columns)"

-- Glenn (a.k.a. Le Grand Typo)
sed 's/this is a test/&  &/g' textfile

will return:
this is a test this is a test

so sed will search of this is a test and the "&" signs will echo whatever it matches on the replace side


hope this helps
sandtrap, do try my example. It will juggle three "matched areas" to more closely mimik the expressed need of copying the first 10 characters to position 30-39, and still retain any data from position 30 to EOL "pushed right" to position 40.

The grouping is done with the \( \) construct, where the first group match \1, the second \2 etc. The actual matching is done via the c\{m,n\} construct, where c == character to match ("." in this case, which match any character), m == least amount of matches and n = upper limit.

But as stated (or rather implied) in my earlier comment, sed is silly here since it will only operate correctly under a limited set of assumptions, and it is very difficult to make it more generic than my suggestion. Many have already suggested awk/gawk which is fine (apart from the limitations:-). Normally I'd do this kind of thing with perl.

-- Glenn
PS for Hans-Erik Skyttberg. Are you swedish? Ever go to the university of Luleå?
DS
Hi!

Yes, I'm swedish no I never went to Lulee, only Umea.

Regards
/Hans - Erik Skyttberg
Ok, I wen't to Lulea ... some time ago:-) (I can't believe EE isn't 8-bit clean... I typed "a ring":-). Used to be a very intelligent person by name of .. Hans-Erik S...berg, who I've completely lost contact with. Turns out it was Sandberg, not Skyttberg.

Fun to see a countryman though;-)

-- Glenn