Pregunta

I have an input stream like this:

afs=1;bgd=1;cgd=1;djh=1;fgjhh=1;

Now the rule I have to edit the stream is: (1)if we have

"djh=number;"

replace it with

"djh=number,"

(2)else replace "string=number;"it with

"string,"

I can handle case 2 as:

sed 's/afs=1/afs,/g;s/dbg=1/dbg,/g;..... so on for rest

How to take care for condition 1?

The "djh" number can be any number(1,12,100), the other numbers are always 1.

all the double quotes I have used are for reference only; no double quotes are present in the input stream. "afs" can be "Afs" also. Thanks in advance.

¿Fue útil?

Solución

sed -e 's/;/,/g; s/,djh=/,@=/; s/\([a-z][a-z]*\)=[0-9]*,/\1,/g; s/@/djh/g'

This does the following

  1. replace all ; by ,
  2. replace djh with @
  3. remove =number from all lower cased strings
  4. replace @ with djh

This results in afs,bgd,cgd,djh=1,fgjhh, for your input. Of course you could substitute djh with any other character that makes it easy to match the other strings. This is just illustrating the idea.

Otros consejos

echo 'afs=1;bgd=1;cgd=1;djh=1;fgjhh=1;' | 
sed -e 's/\(djh=[0-9]\+\);/\1,/g' -e 's/\([a-zA-Z0-9]\+\)=1;/\1,/g'

This might work for you:

echo "afs=1;bgd=1;cgd=1;djh=1;fgjhh=1;" |
sed 's/^/\n/;:a;/\n\(djh=[0-9]*\);/s//\1,\n/;ta;s/\n\([^=]*\)=1;/\1,\n/;ta;s/.$//'
afs,bgd,cgd,djh=1,fgjhh,

Explanation:

This method uses a unique marker (\n is a good choice because it cannot appear in the pattern space as it is used by sed as the line delimiter) as anchor for comparing throughout the input string. It is slow but can scale if more than one exception is needed.

  • Place the marker in front of the string s/^/\n/
  • Name a loop label :a
  • Match the exception(s) /\n\(djh=[0-9]*\)/
  • If the exception occurs substitute as necessary. Also bump the marker along /s//\1,\n/
  • If the above is true break to loop label ta
  • Match the normal and substitute. Also bump the marker along s/\n\([^=]*\)=1;/\1,\n/
  • If the above is true break to loop label ta
  • All done remove the marker s/.$//

or:

echo "afs=1;bgd=1;cgd=1;djh=1;fgjhh=1;" | 
sed 's/\<djh=/\n/g;s/=[^;]*;/,/g;s/\n\([^;]*\);/djh=\1,/g'
afs,bgd,cgd,djh=1,fgjhh,

Explanation:

This is fast but does not scale for multiple exceptions:

  • Globaly replace the exception string with a new line s/\<djh=/\n/g
  • Globaly replace the normal condition s/=[^;]*;/,/g
  • Globaly replace the \n by the exception string s/\n\([^;]*\);/djh=\1,/g

N.B. When replacing the exception string make sure that it begins on a word boundary \<

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top