0

I'm trying to find the solution for search and replace in WordPress export XML file that will:

  1. find string

    <content:encoded><![CDATA[HERE GOES ANY POSSIBLE POSTS TEXT including HTML tags]]></wp:meta_value>
    
  2. replace closing tag </wp:meta_value> with </content:encoded>

The problem is that XML file has lot of other closing </wp:meta_value> tags - not only for starting <content:encoded>.

Any sed solutions I searched didn't help. Is it doable with any bash commands?

PS: My goal is to convert custom field to the default WP content tag. The original code I need to change is like:

    <wp:postmeta>
        <wp:meta_key><![CDATA[page_content_0_text]]></wp:meta_key>
        <wp:meta_value><![CDATA[POST CONTENT GOES HERE]]></wp:meta_value>
    </wp:postmeta>

And I need:

<content:encoded><![CDATA[POST CONTENT GOES HERE]]></content:encoded>

<content:encoded> is unique for each post in XML and <wp:postmeta> is not.

10
  • Use an XML-aware tool, e.g. xmlstarlet or xsh.
    – choroba
    Jul 18 at 21:39
  • This is a programming, not a unix question. Also, as choroba said, sed is the wrong tool to parse XML. I'm not aware of any bash builtins that can parse XML (Pretty certain there are none). But there's certainly quite a few command line tools that can parse XML. Jul 18 at 23:05
  • @choroba. XML-aware tools expect valid and well-formed XML. This is not the case here.
    – fpmurphy
    Jul 19 at 0:54
  • @MarcusMüller No XML parser would parse this text file correctly.
    – Kusalananda
    Jul 19 at 6:30
  • 1
    Did you, by any chance, edit the start tags yourself? Or did you modify the CDATA section so that the tags became unmatched?? If Wordpress exported an XML file with unbalanced tags, you may want to file a bug report against that software. If you edited this data, then consider posting the original data and let us know in what way you intended to change it.
    – Kusalananda
    Jul 19 at 6:32
1

We will exploit the property of a CDATA section ,viz., that it cannot contain the substring ]]> within it:

perl -0777 -pe '
  s{
    <content:encoded>
    <!\[CDATA\[.*?]]> \K
    </wp:meta_value>
  }[</content:encoded>]xgs;
' your_file.input
1
  • Worked like a charm, thanks!
    – Alex
    Jul 19 at 10:59

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.