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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.