Question

I have a folder structure, as shown below:

alt text

I need to create a bash script that does 4 things:

  1. It searches all the files in the generic directory and finds the string 'generic' and makes it into 'something'
  2. As above, but changes "GENERIC" to "SOMETHING"
  3. As above, but changes "Generic" to "Something"
  4. Renames any filename that has "generic" in it with "something"

Right now I am doing this process manually by using the search and replace in net beans. I dont know much about bash scripting, but i'm sure this can be done. I'm thinking of something that I would run and it would take "Something" as the input.

Where would I start? what functions should I use? overall guidance would be great. thanks.

I am using Ubuntu 10.5 desktop edition.

Was it helpful?

Solution

Editing

The substitution part is a sed script - call it mapname:

sed -i.bak \
    -e 's/generic/something/g' \
    -e 's/GENERIC/SOMETHING/g' \
    -e 's/Generic/Something/g "$@"

Note that this will change words in comments and strings too, and it will change 'generic' as part of a word rather than just the whole word. If you want just the word, then you use end-word markers around the terms: 's/\<generic\>/something/g'. The -i.bak creates backups.

You apply that with:

find . -type f -exec mapname {} +

That creates a command with a list of files and executes it. Clearly, you can, if you prefer, avoid the intermediate mapname shell/sed script (by writing the sed script in place of the word mapname in the find command). Personally, I prefer to debug things separately.

Renaming

The renaming of the files is best done with the rename command - of which there are two variants, so you'll need to read your manual. Use one of these two:

find . -name '*generic*' -depth -exec rename   generic something   {} +

find . -name '*generic*' -depth -exec rename s/generic/something/g {} +

(Thanks to Stephen P for pointing out that I was using a more powerful Perl-based variant of rename with full Perl regexp capacity, and to Zack and Jefromi for pointing out that the Perl one is found in the real world* too.)

Notes:

  • This renames directories.
  • It is probably worth keeping the -depth in there so that the contents of the directories are renamed before the directories; you could otherwise get messages because you rename the directory and then can't locate the files in it (because find gave you the old name to work with).
  • The more basic rename will move ./generic/do_generic.java to ./something/do_generic.java only. You'd need to run the command more than once to get every component of every file name changed.

* The version of rename that I use is adapted from code in the 1st Edition of the Camel book.

OTHER TIPS

Steps 1-3 can be done like this:

find .../path/to/generic -type f -print0 |
    xargs -0 perl -pi~ -e \
        's/\bgeneric\b/something/g; 
         s/\bGENERIC\b/SOMETHING/g;
         s/\bGeneric\b/Something/g;'

I don't understand exactly what you want to happen in step 4 so I can't help with that part.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top