Operating System - HP-UX
1833786 Members
2763 Online
110063 Solutions
New Discussion

problem with sed 'ing a section of text

 
SOLVED
Go to solution
Bill McNAMARA_1
Honored Contributor

problem with sed 'ing a section of text

I've a small script that looks for n lines after a search.

refering to the script, the
for LINE in .. cmd works fine without the for.

That is, I get the right output from the sed command until it goes into the for statement.

The for LINE seems to look for white spaces and delimit further..

see op of script

# ./sed.scr ABC 5 /etc/opt/ABC/config/abc.conf "#"|more
---------
[ABC]
RunDirectory = /opt/ABC/bin
RunString = /opt/ABC/bin/start
ProcessType = RS
RestartDelay = 15
---------
# [ABC]
# RunDirectory
# =
# /opt/ABC/bin
# RunString
# =
# /opt/ABC/bin/start
# ProcessType
# =
# RS
# RestartDelay
# =
# 15

and script:

#!/usr/bin/ksh

if [ $# -lt 3 ];
then
echo "\n================================================================"
echo " ERROR: Cannot continue."
echo " You must supply a search string,number of lines and file:"
echo " Example: "
echo " $0 \"ABC\" 5 /etc/opt/ABC/config/abc.conf \"insert\" "
echo "================================================================\n"
exit 1
fi

SEA=$1
LEN=$2
FIL=$3
INS=$4

/usr/bin/sed -n '/'$SEA'/,$p' $FIL |sed -n '1,'$LEN'p' > /tmp/temp
echo "---------"
cat /tmp/temp
echo "---------"
if [ $# = 4 ]; then
for LINE in $(cat /tmp/temp)
do
CHANGETO="$INS $LINE"
echo $CHANGETO
done

elif [ ! $4 = "" ]; then
echo "$4"
fi
echo "do the move...."
rm /tmp/temp

Thanks for any help to get the op looking like this:

# [ABC]
# RunDirectory = /opt/ABC/bin
# RunString= /opt/ABC/bin/start
# ProcessType = RS
# RestartDelay = 15

Later,
Bill
It works for me (tm)
20 REPLIES 20
Bill McNAMARA_1
Honored Contributor

Re: problem with sed 'ing a section of text

mmm.. from the man ksh, seems that the for takes word.
What I need is something that'll take line

then I need to replace the line in the original.

Bill
It works for me (tm)
Santosh Nair_1
Honored Contributor
Solution

Re: problem with sed 'ing a section of text

How about replacing the for with:

cat /tmp/temp|while read LINE
do
... do stuff
done

-Santosh
Life is what's happening while you're busy making other plans
Mark van Hassel
Respected Contributor

Re: problem with sed 'ing a section of text

Bill,

Try:

cat /tmp/temp | while read LINE
do
...
done

HtH
The surest sign that life exists elsewhere in the universe is that none of it has tried to contact us
Bill McNAMARA_1
Honored Contributor

Re: problem with sed 'ing a section of text

the problem now is that the
sed that will do the replacement now only replaces the last occurance and not then entire lot.

cat /tmp/temp | while read LINE
do
CHANGETO="$INS $LINE"
echo $CHANGETO >> /tmp/temp.out
sed "s/$LINE/$CHANGETO/g" $FIL > ${FIL}.bak
done

# cat /tmp/temp.out
# [ABC]
# RunDirectory = /opt/ABC/bin
# RunString = /opt/ABC/bin/start
# ProcessType = RS
# RestartDelay = 15

the only line replaced with the sed is
# RestartDelay = 15

Later,
Bill
It works for me (tm)
Bill McNAMARA_1
Honored Contributor

Re: problem with sed 'ing a section of text

sed "s/$LINE/$CHANGETO/g" $FIL > ${FIL}.bak

The sed does the same input file all the time.. so that's normal.. but now I'm having trouble trying to find a way to do this right..

Later,
Bill
It works for me (tm)
Mark van Hassel
Respected Contributor

Re: problem with sed 'ing a section of text

Without sed ?

cat filename | while read LINE
do
echo "$INS $LINE" >> ${FILE}.bak
done


HtH
The surest sign that life exists elsewhere in the universe is that none of it has tried to contact us
Bill McNAMARA_1
Honored Contributor

Re: problem with sed 'ing a section of text

no, I've got to replace the modified line in the original file.
It works for me (tm)
Robin Wakefield
Honored Contributor

Re: problem with sed 'ing a section of text

Hi Bill,

You have a single redirect ">" within your loop instead of ">>", and so you'll only ever get the last line written to the .bak file.

Rgds, Robin.
Mark van Hassel
Respected Contributor

Re: problem with sed 'ing a section of text

cat $FIL | while read LINE
do
TEMP="${FIL}.tmp"
echo $LINE > $TEMP
sed s"/$LINE/$CHANGETO/g" ${TEMP >>FIL.bak
rm $TEMP
done

HtH
The surest sign that life exists elsewhere in the universe is that none of it has tried to contact us
Bill McNAMARA_1
Honored Contributor

Re: problem with sed 'ing a section of text

Changing the sed to: sed "s:$LINE:$CHANGETO:g" $FIL >> ${FIL}.bak

I end up with an output that
has the input file $FIL
cat'd $2 times with each occurance of $FIL having just one change.. the current line the while was on.

# more /tmp/abc.conf
[ABC]
RunDirectory = /opt/ABC/bin
RunString = /opt/ABC/bin/startABC
ProcessType = RS
RestartDelay = 15
Resources = DISK+MEM+LAN
StdoutFile = /tmp/ABC.out
StderrFile = /tmp/ABC.err
AutoStart = Yes
PreferredProcessor = 0

ie:

[ABC]
# RunDirectory = /opt/ABC/bin
RunString = /opt/ABC/bin/startABC
ProcessType = RS
RestartDelay = 15
Resources = DISK+MEM+LAN
StdoutFile = /tmp/ABC.out
StderrFile = /tmp/ABC.err
AutoStart = Yes
PreferredProcessor = 0

[ABC]
RunDirectory = /opt/ABC/bin
# RunString = /opt/ABC/bin/startABC
ProcessType = RS
RestartDelay = 15
Resources = DISK+MEM+LAN
StdoutFile = /tmp/ABC.out
StderrFile = /tmp/ABC.err
AutoStart = Yes
PreferredProcessor = 0

[ABC]
RunDirectory = /opt/ABC/bin
RunString = /opt/ABC/bin/startABC
# ProcessType = RS
RestartDelay = 15
Resources = DISK+MEM+LAN
StdoutFile = /tmp/ABC.out
StderrFile = /tmp/ABC.err
AutoStart = Yes
PreferredProcessor = 0

[ABC]
RunDirectory = /opt/ABC/bin
RunString = /opt/ABC/bin/startABC
ProcessType = RS
# RestartDelay = 15
Resources = DISK+MEM+LAN
StdoutFile = /tmp/ABC.out
StderrFile = /tmp/ABC.err
AutoStart = Yes
PreferredProcessor = 0
It works for me (tm)
Bill McNAMARA_1
Honored Contributor

Re: problem with sed 'ing a section of text

# ./sed.scr ABC 5 /tmp/ftt.conf "#"
---------
[ABC]
RunDirectory = /opt/ABC/bin
RunString = /opt/ABC/bin/startABC
ProcessType = RS
RestartDelay = 15
---------
[# [ABC]# [ABC]# [ABC]]
# RunDirectory = /opt/ABC/bin
RunString = /opt/ABC/bin/startABC
ProcessType = RS
# RestartDelay = 15
kibo(root) /


#!/usr/bin/ksh

if [ $# -lt 4 ];
then
echo "\n================================================================"
echo " ERROR: Cannot continue."
echo " You must supply a search string,number of lines and file:"
echo " Example: "
echo " $0 \"ABC\" 5 /etc/opt/ABC/config/abc.conf \"#\" "
echo "================================================================\n"
exit 1
fi

SEA=$1
LEN=$2
FIL=$3
INS=$4

export LINES=1
/usr/bin/sed -n '/'$SEA'/,$p' $FIL |sed -n '1,'$LEN'p' > /tmp/temp
echo "---------"
cat /tmp/temp
echo "---------"
if [ $# = 4 ]; then

cat /tmp/temp | while read LINE
do
TEMP="${FIL}.tmp"
echo $LINE > $TEMP
CHANGETO="$INS $LINE"
sed "s:$LINE:$CHANGETO:g" ${TEMP} >> ${FIL}.bak
rm $TEMP
done
fi

rm /tmp/temp
cat ${FIL}.bak
rm ${FIL}.bak


# cat /tmp/abc.conf
[ABC]
RunDirectory = /opt/ABC/bin
RunString = /opt/ABC/bin/startABC
ProcessType = RS
RestartDelay = 15
Resources = DISK+MEM+LAN
StdoutFile = /tmp/ABC.out
StderrFile = /tmp/ABC.err
AutoStart = Yes
PreferredProcessor = 0
It works for me (tm)
Mark van Hassel
Respected Contributor

Re: problem with sed 'ing a section of text

Bill,

Maybe easier:

sed "/^/$INS /" $FILE >$FILE.bak

without the while loop

The surest sign that life exists elsewhere in the universe is that none of it has tried to contact us
Bill McNAMARA_1
Honored Contributor

Re: problem with sed 'ing a section of text

in that case I'd change everything in the file and not just the lines returned by the first sed..

?
It works for me (tm)
Robin Wakefield
Honored Contributor

Re: problem with sed 'ing a section of text

Hi Bill,

Change the central loop to:

cat /tmp/temp | while read LINE
do
TEMP="${FIL}.tmp"
echo $LINE > $TEMP
CHANGETO="$INS $LINE"
echo $LINE | sed 's/\[/\\\\[/g' | read LINE
sed "s:$LINE:$CHANGETO:g" ${TEMP} >> ${FIL}.bak
rm $TEMP
done
fi

The problem is the leading "[" of [ABC] is causing [ABC] to be interpreted as "one of A,B or C", so you need to escape the "[" in the search string.

Rgds, Robin.
Mark van Hassel
Respected Contributor

Re: problem with sed 'ing a section of text

sorry, that should be /tmp/temp instead of $FILE
The surest sign that life exists elsewhere in the universe is that none of it has tried to contact us
Curtis Larson_1
Valued Contributor

Re: problem with sed 'ing a section of text

have you thought about using awk for this

cat $FIL |
awk '
/'$SEA'/ { occurance++;
if ( occurance <= '$LEN' ) {
print "'$INS'" " " $0;
next;
}
}
{print $0}' > $FIL.bak
Bill McNAMARA_1
Honored Contributor

Re: problem with sed 'ing a section of text

that was close Robin, however it just appends to the file now rather than replacing the old text.

ie the first sed works to find the search string plus $2 lines after and the second sed is meant to replace those lines not add them on to the end.

The awk was very close, although seems to be a bug..

see output:

# cat /tmp/abc.conf
[XYZ]
hello = bonjour

[ABC]
RunDirectory = /opt/ABC/bin
RunString = /opt/ABC/bin/startABC
ProcessType = RS
RestartDelay = 15
Resources = DISK+MEM+LAN
StdoutFile = /tmp/ABC.out
StderrFile = /tmp/ABC.err
AutoStart = Yes
PreferredProcessor = 0

[BOB]
bob = robert

modified with awk in place of loop:

# [ABC]
# RunDirectory = /opt/ABC/bin
# RunString = /opt/ABC/bin/startABC
ProcessType = RS
RestartDelay = 15
Resources = DISK+MEM+LAN
# StdoutFile = /tmp/ABC.out
StderrFile = /tmp/ABC.err
AutoStart = Yes
PreferredProcessor = 0

It works fine up to 3 lines!?

Later,
Bill
It works for me (tm)
Bill McNAMARA_1
Honored Contributor

Re: problem with sed 'ing a section of text

the occurance variable in the awk just searches for the number of occurance of the SEA search string.

But the SEA search string is used to find $LEN lines after the first SEA occurance.
so occurance needs to be calculated on LEN..

Bill
It works for me (tm)
Curtis Larson_1
Valued Contributor

Re: problem with sed 'ing a section of text

if the output isn't correct there would have to be something not correct. But without your script that will be hard to determine.

but my results for file:

[XYZ]
hello = bonjour

[ABC]
RunDirectory = /opt/ABC/bin
RunString = /opt/ABC/bin/startABC
ProcessType = RS
RestartDelay = 15
Resources = DISK+MEM+LAN
StdoutFile = /tmp/ABC.out
StderrFile = /tmp/ABC.err
AutoStart = Yes
PreferredProcessor = 0

[BOB]
bob = robert

with the script:

#!/usr/bin/ksh

FIL=./f2
SEA=ABC
LEN=5
INS=#

cat $FIL |

awk '
/'$SEA'/ { occurance++;
if ( occurance <= '$LEN' ) {
print "'$INS'" " " $0;
next;
}
}
{ print $0;} ' > $FIL.bak

results in:

[XYZ]
hello = bonjour

# [ABC]
# RunDirectory = /opt/ABC/bin
# RunString = /opt/ABC/bin/startABC
ProcessType = RS
RestartDelay = 15
Resources = DISK+MEM+LAN
# StdoutFile = /tmp/ABC.out
# StderrFile = /tmp/ABC.err
AutoStart = Yes
PreferredProcessor = 0

[BOB]
bob = robert
Bill McNAMARA_1
Honored Contributor

Re: problem with sed 'ing a section of text

This works!!

SEA=$1
LEN=$2
FIL=$3
INS=$4

/usr/bin/sed -n '/'$SEA'/,$p' $FIL |sed -n '1,'$LEN'p' > /tmp/temp

if [ $# = 4 ]; then
cat /tmp/temp | while read LINE
do
CHANGETO="$INS $LINE"
echo $LINE | sed 's/\[/\\\\[/g' | read LINE
sed "s:$LINE:$CHANGETO:g" ${FIL} > ${FIL}.bak
mv ${FIL}.bak $FIL
done
fi
It works for me (tm)