Saturday, July 31, 2010

Bash shell tricks

Tarring files recursively with filter

to create:
find . -name *.out | xargs tar cvf cohservernodes.tar

to append:
find . -name *.log | xargs tar rvf cohservernodes.tar

to list:
tar tf cohservernodes.tar


Find a text in files, recursively:

find . | xargs grep -s whatever



find and replace recursively

for file in $(grep -il "whatever" *.txt)
do
sed -e "s/Hello/Goodbye/ig" $file > /tmp/tempfile.tmp
mv /tmp/tempfile.tmp $file
done

how about:

perl -p -i -e 's/oldstring/newstring/g' `find ./ -name *.html`

the above command works very well, but if you try

perl -p -i -e 's/oldstring/newstring/g' `find ./ -name *`

you get the error:

Can't do inplace edit: bla is not a regular file, <> line

because it tries to change also the directories

To do a find excluding directories you must do this (add -type f):

perl -p -i -e 's/oldstring/newstring/g' `find ./ -name * -type f`

1 comment:

ole said...

Your use of xargs may be dangerous. If you have more files that will fit on a single line, your tar will be overwritten and only contain the last files.

Your last use of xargs with grep may fail because of the separator problem. See here why http://en.wikipedia.org/wiki/Xargs#The_separator_problem

Consider using GNU Parallel http://www.gnu.org/software/parallel/ instead.

Watch the intro video to GNU Parallel at http://www.youtube.com/watch?v=OpaiGYxkSuQ