Refactoring code with find, xargs and sed

GNU/Linux comes with some fantastic tools, most of which are very specific in what they do, however when joined together they can form a very powerful workflow. The tools I join together on a daily basis are xargs, sed and find.

I'll go over each of these separately first, then talk about joining them together to mass edit many files, something which is needed a lot when programming. In the example, we'll aim to change the name of the class 'FooException' to 'BarException'.

find

Find is a tool that searches for files in a given directory (recursively as well), and is where our tool set starts. There are many configuration options for Find, however I shall just go over some basics that are enough for the usage we need. A full indepth manual for Find can be found in the 'find' man page.

To start, we'll find all files within a specified directory:

find ./dir/ -type f

This should now display all files within the './dir' directory and all sub folders (recursively). '-type f' controls what should be found, in the case the 'f' stands for 'files'. When we are wanting to mass edit PHP files though, we'll want to make sure we get just PHP files and not every single file. Find supports the '-name' argument which lets us do this easily:

find ./dir -name *.php

Sometimes you will only want to search within a directory and not the sub folders, this can be achieved by using the '-maxdepth' argument, such as :

find ./dir -maxdepth 1 -name *.php

xargs

xargs lets us build and execute commands from the standard input, and will let us link up a few command easily. While xargs is not actually required for what we are aiming at doing, I find it easier and quicker to use than just the 'find' tool.

I wont go into depth with xargs, since we'll only be using it at the very basic level. In the below example, we'll take the input from the last above 'find' command, and use it with 'xargs' and 'echo' to change the output:

find ./dir -maxdepth 1 -name *.php | xargs echo foo

Each file that 'find' found, should now be prefixed with 'foo'.

sed

sed is a Stream EDitor which allows us to performance text transformations using regex. This tool will give us the magic in mass text replacement to rename our classes. Below is a very basic example of using sed to transform text:

echo foo | sed 's/f/b/g'

This will output 'boo'. What happens here is sed is finding all occurrences of 'f' and replacing them with 'b', resulting in 'foo' becoming 'boo'. Learning regular expressions is outside of the scope or this article, and I am going to assume you have knowledge of it.

Linking them all up

So now we want to change the name of a class in our PHP application, 'FooException' to 'BarException'. You could go around every single file, and change them manually however for a big application that could take a very long time. Instead we shall use the tools above to do it for us in seconds:

find ./dir -name *.php | xargs sed -i 's/FooException/BarException/gi'

The '-i' argument we pass to 'sed' tells it to edit the file in place, without it the file would not be edited, there are also 2 regular expression modifiers that I use, 'g' and 'i'. The first one, 'g' tells it to replace all occurrences of it in a single line, without it if there are multiple 'FooException' strings on one line, only the first will be replaced. The latter, 'i' makes it case-insensitive, meaning it will match for 'fooexception', 'fooExCeption' etc.

That is all there is to it. Changing a class name over for an entire application is something that can be done in seconds thanks to the above tools. Of course you can do more major changes to your code, but this is purely an example of what can be done.

Comments

There are no comments for this post

Leave a comment

Antispam code

Enter the text you see to the left

Web Design Shrewsbury telephone 08000 805401

Web Design Manchester telephone 0161 7440075

Web Design Birmingham telephone 0121 7750085

Web Design London telephone 0207 1250044

Valid XHTML/CSS © Mutiny Design - Website Design and Development - Network House, Badgers Way, Oxon Business Park, Shrewsbury, Shropshire SY3 5AB