1

For a migration process, I need to do some replacement in my bash script.

So in my .txt files, I have these references for example:

{{Info DOC
|author= ME
|company= MY COMPANY
|classification= RESTRICTED
}}

What I need to do is to edit all these occurrences with this format:

=== Info DOC ===
|author= ME
|company= MY COMPANY
|classification= RESTRICTED
  1. {{ }} removed.
  2. === === added on first line.

I tried to do a is to build sed regex to do a substitution

sed -i -e 's/{{Info DOC/=== Info DOC ===/g' test_file.txt

So, it's working as expected, but a can't do the same for string "}}" as it will match more things as expected.

I'm trying to achieve it with something like this:

find . -name '*.txt' -exec perl -i -pe 's/{{Info DOC\(.*\)}}/=== Info DOC ===\n\1/g' {} \;

If you have some clues for me, it will be great ! Thank you all !

Final Solution: (thank you @Sundeep)

find . -name '*.txt' -exec perl -i -0777 -pe 's/\{\{(Info DOC)(.*?)\}\}\n/=== $1 ===$2/sg' {} \;

PS: I'm on MacOS system and use bash v4

  • what's your sed --version? – RomanPerekhrest Apr 5 '18 at 9:44
  • @RomanPerekhrest unable to use this arg to view version of sed on macOS :/ – Sébastien Robert Apr 5 '18 at 9:54
  • @don_crissti sorry, just clarified my first post. Yes I want to get rid of opening and closing braces and edit first line by adding "= " characters. – Sébastien Robert Apr 5 '18 at 11:38
1

Try these:

$ # tested on GNU-sed, not sure of syntax for other versions
$ sed '/{{Info DOC/,/}}/ { s/{{\(Info DOC\)/=== \1 ===/; /}}/d }' ip.txt
=== Info DOC ===
|author= ME
|company= MY COMPANY
|classification= RESTRICTED
  • /{{Info DOC/,/}}/ from line containing {{Info DOC to line containing }} (see Range Addresses for details)
    • s/{{\(Info DOC\)/=== \1 ===/ transform as needed
    • /}}/d delete this one
    • rest of the lines won't be changed


With perl

$ perl -0777 -pe 's/\{\{(Info DOC)(.*?)\}\}\n/=== $1 ===$2/sg' ip.txt
=== Info DOC ===
|author= ME
|company= MY COMPANY
|classification= RESTRICTED
  • -0777 slurp entire file, so this solution not suited for too big an input file
  • .*? non-greedy matching
  • s modifier to allow . to match newline character as well
  • sed suggestion works great on single file, if I want to use it on multiple files with ‘find . -type f -name '*.txt' -exec gsed '/{{Info DOC/,/}}/ { s/{{(Info DOC)/=== \1 ===/; /}}/d }' {} +‘ seems not working. (gsed is used on macOS for GNU SED) – Sébastien Robert Apr 5 '18 at 12:17
  • could you elaborate what is not working? is there an error? file not changed? etc... for inplace editing, you'd need to add -i option... – Sundeep Apr 5 '18 at 12:37
  • 1
    Sorry it's working great now, I option was misplaced during my tests, working as expected, thank you for your time ! – Sébastien Robert Apr 5 '18 at 12:56

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.