Replace all but skip first instance in a line

I have a record like the one given below.

010000306551~IN ~N~ |WINDWARD PK|Alpharetta|

If ~ is present more than instance in a line,then I need to delete those instances.

Any ideas?

I am working in Solaris

It would help if you provided a few sample lines and how they should appear after processing.

Regards,
Alister

The above given text should look like
010000306551~IN N |WINDWARD PK|Alpharetta|

Hmmm.

Splitting the spring apart with IFS="~" would delete all the ~'s and remember where they belonged. IFS="" ; echo "$" will put the string back together with no ~'s at all. So you save and shift away the first parameter, then mash the rest together with $, and put them together with ~ in the middle.

#!/bin/ksh

while read LINE
do
        IFS="~"
        # Break into $1, $2, ... $N based on IFS
        set -- $LINE

        # More than 2 chunks means it found more than one ~
        if [ "$#" -gt 2 ]
        then
                VAR="${1}"
                #toss $1, $2 becomes $1, $3 becomes $2, etc.
                shift
                # IFS affects how $* expands.
                IFS=""
                echo "${VAR}~${*}"
        else
                # Print the unmodified line.  We don't need to delete anything.
                echo "$LINE"
        fi        
done
$ ./ifsplit.sh <<EOF
010000306551~IN ~N~ |WINDWARD PK|Alpharetta|
a~b~c~d~e
a
b
c~d

EOF
010000306551~IN N |WINDWARD PK|Alpharetta|
a~bcde
a
b
c~d
$

You'd use it like

./ifsplit.sh < input > temp ; cat temp > input ; rm temp

Thanks Corona688.

This actually breaks the line into multiple chunks.

Ideally I just want to replace >1 occurences of ~

It does exactly what you asked for. :confused: It comes in as a single line and leaves as a single line with every ~ beyond the first one removed. The logic's just slightly different than you expected.

String operations like "find the first ~" aren't so easy to do in the shell. In C you could call strchr() but in ksh that could mean 'cut' once for each individual character in a string. So I redefined 'find' a little and let it find the ~'s by splitting, then put the split string back together the way you wanted it.

Thank you so much.It works.

My bad I was executing in a wring shell where I had already switched the IFS

A sed alternative:

sed 's/~/\
/; s/~//g; s/\n/~/'

Since we are guaranteed that initially there will not be any newlines in sed's pattern space, we can substitute the first occurrence of ~ with a newline. Then we can delete any remaining ~ before restoring the newline back to a ~.

Regards,
Alister