[SOLVED] How can I do a massive find and replace using regular expression?

About writing shell scripts and making the most of your shell
Forum rules
Topics in this forum are automatically closed 6 months after creation.
Locked
fricco

[SOLVED] How can I do a massive find and replace using regular expression?

Post by fricco »

Hello, I need to find and remove in more than 400 files a specific test. This files are XML files and for example I have a file with the following text:

Code: Select all

    <fieldPermissions>
        <editable>true</editable>
        <field>Quote__c.System_Pin__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <fieldPermissions>
        <editable>true</editable>
        <field>Quote__c.Tax_Type_Client_Fee__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <fieldPermissions>
        <editable>true</editable>
        <field>Quote__c.Tax_Type_Marketing_Fee__c</field>
        <readable>true</readable>
    </fieldPermissions>
    <fieldPermissions>
        <editable>true</editable>
        <field>Quote__c.Tax_Type_Risk_Fee__c</field>
        <readable>true</readable>
    </fieldPermissions>
And remove the complete section that goes:

Code: Select all

    <fieldPermissions>
        <editable>true</editable>
        <field>Quote__c.Tax_Type_Client_Fee__c</field>
        <readable>true</readable>
    </fieldPermissions>
Nowadays I'm using Sublime Text doing a search with the following regular expression:

Code: Select all

\s*<fieldPermissions>\r?\n\s*<editable>(false|true)<\/editable>\r?\n\s*<field>Quote__c.Tax_Type_Client_Fee__c<\/field>\r?\n\s*<readable>(false|true)<\/readable>\r?\n\s*<\/fieldPermissions>\r?\n\s*
This basically freezes Sublime Text as there are lot of files that match. So I'm looking to see if there is a way to do this from command line, expecting to have it done quicker as it doesn't use a UI.
I tried with sed:

Code: Select all

sed "s/\s*<fieldPermissions>\r?\n\s*<editable>(false|true)<\/editable>\r?\n\s*<field>Quote__c.Tax_Type_Client_Fee__c<\/field>\r?\n\s*<readable>(false|true)<\/readable>\r?\n\s*<\/fieldPermissions>\r?\n\s*/something/g"
and perl:

Code: Select all

perl -p -e "s/\s*<fieldPermissions>\r?\n\s*<editable>(false|true)<\/editable>\r?\n\s*<field>Quote__c.Tax_Type_Client_Fee__c<\/field>\r?\n\s*<readable>(false|true)<\/readable>\r?\n\s*<\/fieldPermissions>\r?\n\s*/something/g"
with no luck.
Any clue on how to do this, if it's even possible?
Last edited by LockBot on Wed Dec 28, 2022 7:16 am, edited 2 times in total.
Reason: Topic automatically closed 6 months after creation. New replies are no longer allowed.
User avatar
JerryF
Level 16
Level 16
Posts: 6570
Joined: Mon Jun 08, 2015 1:23 pm
Location: Rhode Island, USA

Re: How can I do a massive find and replace using regular expression?

Post by JerryF »

Check out these posts. I think they may help:
viewtopic.php?f=47&t=240027&p=1314934&h ... e#p1314934
fricco

Re: How can I do a massive find and replace using regular expression?

Post by fricco »

JerryF wrote:Check out these posts. I think they may help:
viewtopic.php?f=47&t=240027&p=1314934&h ... e#p1314934
Thanks, but in here are talking about UI text editors, which will hav the same issues I'm having with Sublime Text. What I'm looking for is using something from the command line to avoid the load and display of the 400 files
Lemongrass38

Re: How can I do a massive find and replace using regular expression?

Post by Lemongrass38 »

.
FreedomTruth
Level 4
Level 4
Posts: 443
Joined: Fri Sep 23, 2016 10:19 am

Re: How can I do a massive find and replace using regular expression?

Post by FreedomTruth »

use sed? http://www.grymoire.com/Unix/Sed.html#uh-51a

Code: Select all

sed '
/<fieldPermissions>/ {
   N
   N
   /Quote__c.Tax_Type_Client_Fee__c/ {
      N
      N
      /<\/fieldPermissions>/d
   }
}
'
You still need to handle input/output but the above code should do what you want, I hope.
fricco

Re: How can I do a massive find and replace using regular expression?

Post by fricco »

FreedomTruth wrote:use sed? http://www.grymoire.com/Unix/Sed.html#uh-51a

Code: Select all

sed '
/<fieldPermissions>/ {
   N
   N
   /Quote__c.Tax_Type_Client_Fee__c/ {
      N
      N
      /<\/fieldPermissions>/d
   }
}
'
You still need to handle input/output but the above code should do what you want, I hope.
Wow, yes it did! Any idea now how can I use this script to update the same file? When I tried file.xml > file.xml the result was an empty file.xml
rene
Level 20
Level 20
Posts: 12212
Joined: Sun Mar 27, 2016 6:58 pm

Re: How can I do a massive find and replace using regular expression?

Post by rene »

Use sed -i -e "script" input.xml for in-place editing of input.xml. sed -i.orig -e "script" input.xml for the same while backing up the original input.xml to input.xml.orig.
WharfRat

Re: How can I do a massive find and replace using regular expression?

Post by WharfRat »

You should be able to incorporate find to go through all of the files e.g., find /usr/share/dbus-1/ -iname *.xml -exec cat '{}' \; replacing cat with your sed directive.

I would copy your target files to another location and test it first.
lmuserx4849

Re: How can I do a massive find and replace using regular expression?

Post by lmuserx4849 »

Incorporate FreedomTruth's sed into bash.

Code: Select all

#!/bin/bash
declare -- file=''
declare -- dir="$HOME"                              # ** change **
declare -- backup='/tmp/backup/'                # ** change **
declare -- log="/tmp/backup/${0##*/}.log"   # ** change **
declare -- rc=0

if [[ ! -d "${backup}" ]]; then
  mkdir "${backup}"
  printf -- 'Created directory %s\n' "${log}" >> "${log}"
fi

while read -re -d $'\0' file; do

  printf -- 'Processing %s\n' "${file}" >> "${log}"
  cp -a "${file}" "${backup}"

  sed -i '
  /<fieldPermissions>/ {
    N
    N
    /Quote__c.Tax_Type_Client_Fee__c/ {
        N
        N
        /<\/fieldPermissions>/d
    }
  }
  ' "${file}"

  rc=$?
  if (( "${rc}" != 0 )); then
    printf 'sed exit status not 0 [%s]' "${rc}"
    exit 1
  fi

done < <(find "${dir}" -name '*.xml' -print0)   # ** change as needed **
fricco

Re: How can I do a massive find and replace using regular expression?

Post by fricco »

Thanks everyone, great advices. I will try them today and will mark the post as SOLVED once I confirm is working. But again, THANKS!
Locked

Return to “Scripts & Bash”