-1

i have this xml text in file named test2.txt

<This is a line of text with a year=2020 month=12 in it
This line of text does not have a year or month in it
This year=2021 is the current year the current month=1
This is the year=2021 the month=2/>


<This is a line of text with a year=33020 month=12 in it
This line of text does not have a year or month in it
This year=33020 is the current year the current month=1
This is the year=33020 the month=2/>

im running this regexp on the file : i like to commnet the first paragraph but leaving the rest of the file as is

sed -i -En '/./{H;$!d} ; x ; s/<(This.*2020.*)\/>/<!--\1-->/p' test2.txt

but the result is that the sed command removing all the rest of the string in the file and putting the result of the regexp init so now the test2.txt looks like this :

<!--This is a line of text with a year=2020 month=12 in it
This line of text does not have a year or month in it
This year=2021 is the current year the current month=1
This is the year=2021 the month=2-->

how can i run the regexp but leave the other text in the file ?

1
3

You are explicitly telling sed not to print unless the line matches the pattern. So, simply remove the -n and the p after the s/// operator, and it will work as you expect:

$ sed  -E '/./{H;$!d} ; x ; s/<(This.*2020.*)\/>/<!--\1-->/'  file

<!--This is a line of text with a year=2020 month=12 in it
This line of text does not have a year or month in it
This year=2021 is the current year the current month=1
This is the year=2021 the month=2-->


<This is a line of text with a year=33020 month=12 in it
This line of text does not have a year or month in it
This year=33020 is the current year the current month=1
This is the year=33020 the month=2/>

This is still adding an extra newline at the beginning, however. Luckily, @Philippos told me how to fix that, so use this instead:

$ sed -E '/./{H;1h;$!d} ; x ; s/<(This.*2020.*)\/>/<!--\1-->/'  file
<!--This is a line of text with a year=2020 month=12 in it
This line of text does not have a year or month in it
This year=2021 is the current year the current month=1
This is the year=2021 the month=2-->


<This is a line of text with a year=33020 month=12 in it
This line of text does not have a year or month in it
This year=33020 is the current year the current month=1
This is the year=33020 the month=2/>

Or, to edit the original file:

sed -i.bak -E '/./{H;1h;$!d} ; x ; s/<(This.*2020.*)\/>/<!--\1-->/'  file
0

Assuming that your data represents some generic XML document: A generic XML node can't be commented out in the manner which you suggest as an attribute could contain the substring --, which would end the comment prematurely, breaking the structure of the document. It would be safer to just delete the node, which is trivial with an XML parser.

Assuming that you have the document

<?xml version="1.0"?>
<root>
  <thing alt="--" year="2019" month="1" day="1"/>
  <thing alt="--" year="2020" month="5" day="13"/>
  <thing year="2021" month="7" day="3"/>
</root>

... and that you'd like to remove the thing nodes that have the value 2020 in their year attribute, using xmlstarlet:

$ xmlstarlet ed -d '//thing[@year = "2020"]' file.xml
<?xml version="1.0"?>
<root>
  <thing alt="--" year="2019" month="1" day="1"/>
  <thing year="2021" month="7" day="3"/>
</root>

xmlstarlet supports in-place editing with its -L (--inplace) option.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.