开发者

How do I write a bash script to replace words in files and then rename files?

I have a folder structure, as shown below:

How do I write a bash script to replace words in files and then rename files?

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&quo开发者_Go百科t; 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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜