Thursday, December 23, 2010

Tarfile with exclude: Linux vs. Solaris

There are differences, yes, and not only in tar syntax. But I'm going to stick to tar (for the moment).
I sometimes have to make a tar file excluding certain directories or files, and it's subtly different in linux from solaris.
For example, we want to create a tar file from a directory called ./mydir, name the output file mydir.tar(.gz) and we put into ./mydir/Exclude a list of files to be excluded from the resulting tar file.
Solaris version:

tar cvfX mydir.tar ./mydir/Exclude ./mydir

will create a tar file called mydir.tar containing all subdirectories of ./mydir and at extraction time it will create a directory ./mydir as well

Linux version:

tar -cvf  mydir.tar --exclude=Exclude ./mydir

or, if you directly want a gzip file:

tar -zcvf  mydir.tar --exclude=Exclude ./mydir


where the contents of the exclude file ./mydir/Exclude are in both cases identical, and for example like (it's assumend to be the relative path to ./mydir):

Exclude
foo
bar


So that's pretty much it. It's very easy, but I always get confused about it, and the differences existing between linux and the Solaris only make all worse to remember.

Wednesday, December 15, 2010

Recursively rename files

I know, I know that's a very easy one... but just when I should have known how to do that in a shot, I didn't. And of course there are a lot of references for such things out there, so I'm absolutely not claiming to be original, but sorry if I don't post any references.
So, here is the thing: imaging you want to rename all files in a certain directory that are *.txt with *.back for example, including any subdirectories:

find . -type f -name "*.txt" -print| rename -n 's/(.*)txt$/$1back/g'

Remarks:
- this works only on linux (or where you have the command 'rename')
- rename accepts the perl regexp syntax, hence all this $1 for the substitution of the previous match (.*)
- tip: it's good to try using rename with -n option, which actually does nothing but showing what it would do without the -n option
- careful: if you fear that something nasty could happen with very depth directories and the find consuming lots of CPU or for whatever reason, you can include a -maxdepth 10 (or any other reasonable number), like this:

find . -maxdepth 10  -type f -name "*.txt" -print| rename -n 's/(.*)txt$/$1back/g'


- another thing that confused me as I tried it out: don't include the 'usual' *.[file_type] (in my case *.txt) at the end, after the rename 's/.../.../' part; it will prevent find from really diving into the subdirectories