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.
sed
' enclose First parameter / Script
/.../ for lines only matching ... pattern
{ start compound statement
s/.../.../ substitute pattern(s)
; separate Statements
} end compound Statement
' end parameter
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...
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.
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"?