3

Declaring bankruptcy after an hour trying to solve this. Here's the question:

I have a folder with 15,000 files (Magento). I want to change all copyright dates from 2013 to 2012 so I can get a legitimate diff between releases. I'm trying to use sed, based on this example: https://stackoverflow.com/a/1583282

This command is working:

cd path/to/project
find . -type f -print0 | xargs -0 sed -i '' 's/2013/2012/g'

Except, I obviously can't trust that 2013 only applies to dates. The full string in Magento's DocBlocks is:

* @copyright   Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)

I'm trying to rewrite the sed expression to use "(c) 2013 Magento" as the string, but I'm getting the error:

sed: RE error: illegal byte sequence

Obviously, something needs to be escaped but I can't find any applicable examples. I am not a bash-wizard by any means.

What's the correct format for this segment of the expression?

's/(c) 2013 Magento/(c) 2012 Magento/g'
Community
  • 1
  • 1
Brendan Falkowski
  • 733
  • 1
  • 5
  • 17

4 Answers4

3

Obviously, something needs to be escaped but I can't find any applicable examples. I am not a bash-wizard by any means

Whatever sort of wizard you are, you've sent the Stack Overflow dwarfs into Mirkwood. Your problem isn't the command escaping. The following will run fine.

find . -type f -print0 | xargs -0 sed -i '' 's/2013 Magento Inc./2012 Magento Inc./g'

Test this by running it in an empty directory.

$ mkdir tmp-gandalf
$ cd tmp-gandalf
$ find . -type f -print0 | xargs -0 sed -i '' 's/2013 Magento Inc./2012 Magento Inc./g'

If you had a shell escaping problem, your system would complain about it here.

Here's the problem. The first part of your command finds all the files to operate on

find . -type f -print0

Using -type f finds all the files. Including non-text files. The sed command doesn't like non-text files. Try something like this

sed -i '' 's/2013 Magento Inc./2012 Magento Inc./g' /path/to/some.gif
find . -name '*.php' -o -name '*.xml' -o -name '*.phtml'

Where /path/to/some.gif is a binary file. You'll see your sed: RE error: illegal byte sequence error. That's sed saying "wtf, I'm not as clumsy or random as a blaster. I come from a more civilized age where everything was ASCII".

This Stack Overflow question has a slightly hacky work around (jiggering the LANG attribute). I don't know enough to trust if this is a good idea or not.

My personal approach would be to limit your find such that only files with certain extensions are included. You can specify multiple name patterns with the -o option. So something like this

//NOTE: each -o needs its own -print0
find . -name '*.php' -print0 -o -name '*.xml' -print0 -o -name '*.phtml' -print0 | xargs -0 sed -i '' 's/2013 Magento Inc./2012 Magento Inc./g'

Would search .php, .xml, and .phtml files. You could add js files with another -o -name '*.js'. There should only be a handful of file types in the Magento code base with Copyright notices.

Community
  • 1
  • 1
Alana Storm
  • 164,128
  • 91
  • 395
  • 599
  • The binary file issue makes perfect sense, and thank you for using proper LOTR/SW phrasing so I would understand. Running your final command with multiple name params does execute, but the replacement isn't being written into the files. I understand that's what "sed -i" param is meant to do, but it doesn't seem to be having that effect. I also tried adding {} onto the end (I think this pipes the file list from the "find" command into "sed" but that had no effect. Any ideas? – Brendan Falkowski Nov 01 '13 at 23:00
  • I'm pretty sure you need to add -e so your command would look something like this find . -name "*.xml" -type f -exec sed -i -e 's/RegEx/Replacement/g' {} \; – peekay Nov 05 '13 at 20:01
0

Try this sed:

 sed 's/\(©\) 2013 \(Magento\)/\1 2012 \2/g'
anubhava
  • 761,203
  • 64
  • 569
  • 643
0

find /full/path/to/magento -type f -print0 | xargs -0 sed -i '' 's/(c) 2013 Magento/(c) 2012 Magento/g'

However:

grep -lir -e '2013 Magento' /full/path/to/magento /full/path/to/magento/app/code/core/Enterprise/Enterprise/etc/config.xml /full/path/to/magento/app/code/core/Mage/Page/etc/config.xml /full/path/to/magento/app/locale/en_US/Mage_Page.csv /full/path/to/magento/errors/default/page.phtml /full/path/to/magento/errors/enterprise/page.phtml /full/path/to/magento/downloader/template/footer.phtml /full/path/to/magento/downloader/template/install/footer.phtml

These files will still have "© 2013 Magento" placed in the files

This should work:

find /full/path/to/magento -type f -print0 | xargs -0 sed -i '' 's/2013 Magento/2012 Magento/g'

Richu
  • 1
  • 1
0

Simply escaping the parentheses seems to work for me:

$ sed 's/\(c\) 2013 Magento/\(c\) 2012 Magento/g' <<< "@copyright   Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)"
@copyright   Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
damienfrancois
  • 52,978
  • 9
  • 96
  • 110