Delete special characters

My sed is not working on deleting the entire special characters and leaving what is necessary.

grep connections_per a|sed -e  's/\<\!\-\-//g'

INPUT:

   <!-- <connections_per_instance>1</connections_per_instance> -->
 <method>HALF</method>
          <!-- <connections_per_host>1</connections_per_host> -->
          <dedicated_options_connection>true</dedicated_options_connection>
        </service>
        <service id="half">
          <method>FULL</method>
          <!-- <connections_per_host>1</connections_per_host> -->
          <dedicated_options_connection>true</dedicated_options_connection>

Output:

 <!-- <connections_per_instance>1</connections_per_instance> -->
 <method>HALF</method>
          <connections_per_host>5</connections_per_host>
          <dedicated_options_connection>true</dedicated_options_connection>
        </service>
        <service id="half">
          <method>FULL</method>
          <connections_per_host>5</connections_per_host>
          <dedicated_options_connection>true</dedicated_options_connection>

grep connections_per a|sed -e 's/<!--//g; s/-->//g;'

This does not change the value in the tag as shown in the output.

1 Like

In addition to what rdrtx1 already explained:

If you want to change something only on certain lines and not on others you should do that in sed, not outside, with grep::

sed '/^special_line/ s/Y/X/g'

will change character "Y" to "X", but only on lines starting with "special_line". Likewise with your problem:

sed '/connections_per/ s/[<>]!*--//g' a

If you want only the changed lines as output:

sed -n '/connections_per/ s/[<>]!*--//g' a

As a rule of thumb: whenever you use sed, awk or a similar programmable text processing tool, do everything with it or use another tool. Any line with "...grep | sed | grep..." or "awk | sed | ..." is (very very rare cases aside) nonsense.

I hope this helps.

bakunin

1 Like

Sir can you please copy the text, and test it. Also please check the output.
Thank you

---------- Post updated at 04:12 PM ---------- Previous update was at 04:08 PM ----------

'''do you mind copy the input..

and test it?

and based on my output..hoping it is the same.

sed '/<!--.*<connections_per_host>1</{s/<!--//; s/-->//; s/>.*</>5</};' INPUT
1 Like

Thank you rdxt1, can you please explain, character per character please. the sed command.
Thank you

sed
'            enclose First parameter / Script
/.../        for lines only matching ... pattern
{            start compound statement
s/.../.../   substitute pattern(s)
;            separate Statements
}            end compound Statement
'            end parameter 
2 Likes

I have been looking at the file structure:
1) All lines start with the " ", single space, character as an absolute minimum, are these indents and need to be preserved?
2) If so then line 1 is shifted 2 out of 3 " "'s, 2 spaces, leftwards on the output which implies "NO" to number 1)
3) If indentation IS required then you need to remove <!-- <- note the TRAILING space.
4) Similarly the other end --> <- again note the LEADING space.
5) And leave the 2 lost spaces intact in the first output line.
Just an observation that caught my attention...

1 Like

Your explanation is awesome,...I understand now, what makes me confuse before was, I remember to do a backlash to any special character, But in the command below, theres none.

Thanks

 sed -i '/<!--.*<connections_per_host>1</{s/<!--//; s/-->//; s/>.*</>5</};' a

---------- Post updated at 08:52 AM ---------- Previous update was at 08:51 AM ----------

I like your explanation,. i understand the syantax because of you. But pelase educate me, when to use a backslash to negate a special character?
Thanks

The rule is: when you use a character that has a special meaning (to sed) and you want it to mean just the character itself you need to "escape" it - that is, prepend it with a backslash.

An example:

sed 's/abc./xyz/' /input/file

The dot (".") here doesn't mean a dot, but is a special character, meaning "any one character". If you want it to mean a real, literal dot and nothing else, you need to escape it:

sed 's/abc\./xyz/' /input/file

Notice that this escaping is implicit in some situations, for instance in "character-classes". Look at the following regular expression:

sed 's/a[bcd]e/xyz/' /input/file

This searches for an "a", followed by either an "b", a "c" or a "d", followed by an "e". It would match any of these strings:

abe
ace
ade

Inside the brackets all characters lose their special meaning. I.e. a[bc.]d would search for any of these strings:

abd
acd
a.d

If you would try to escape a character here the escaping backslash would be treated as a normal character too. The regexp a[bc\.]d would find these strings:

abd
acd
a\d
a.d

Notice that the characters you called special - "<", ">", etc. - don't have any special meaning in sed anyway and would have been safe to use without any escaping in first place.

I hope this helps.

bakunin

backslashes don't negate characters, they "escape" them, i.e. remove their special meaning, force them back to normal chars. Negate, BTW, is a difficult term with characters. You might mean "complement"?