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'
4

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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?
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' {} \;
0

Try this sed:

 sed 's/\(©\) 2013 \(Magento\)/\1 2012 \2/g'

2 Comments

Can you try: sed 's/2013.*\(Magento\)/2012 \1/g'
May I know what is your sed version? Since sed 's/2013.*\(Magento\)/2012 \1/g' doesn't have any unicode character
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'

3 Comments

Nope. Getting this error: sed: 1: "./.!14184!.DS_Store": invalid command code .
From this command: find . -type f -print0 | xargs -0 sed -i 's/2013 Magento/2012 Magento/g'
Sorry .. "on Mac" Edited my answer.
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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.