tags:

views:

151

answers:

4

At the moment our backup script explicitly runs svnadmin hotcopy on each of our repositories every night. Our repos are all stored under a parent directory (/usr/local/svn/repos) Our backup script has a line for each of the repos under that directory along the lines of: svnadmin hotcopy /usr/local/svn/repos/myrepo1 /usr/local/backup/myrepo1

Instead of having to manually add a new line for each every new repo we bring online, I was hoping to using the find command to run svnadmin hotcopy for every directory it finds under /usr/local/svn/repos.

So far I've got:

find /usr/local/svn/repos/ -maxdepth 1 -mindepth 1 -type d -exec echo /usr/local/backup{} \;

,where I'm substituting "svnadmin hotcopy" with "echo" for simplicity's sake. The output of which is:

/usr/local/backup/usr/local/svn/repos/ure
/usr/local/backup/usr/local/svn/repos/cheetah
/usr/local/backup/usr/local/svn/repos/casemgt
/usr/local/backup/usr/local/svn/repos/royalliver
/usr/local/backup/usr/local/svn/repos/ure_andras
/usr/local/backup/usr/local/svn/repos/profserv
/usr/local/backup/usr/local/svn/repos/frontoffice
/usr/local/backup/usr/local/svn/repos/ure.orig
/usr/local/backup/usr/local/svn/repos/projectcommon
/usr/local/backup/usr/local/svn/repos/playground
/usr/local/backup/usr/local/svn/repos/casegen

The problem being the full path is included in {}. I need only the last element of the directory name passed to -exec

The output I want being:

/usr/local/backup/ure
/usr/local/backup/cheetah
/usr/local/backup/casemgt
/usr/local/backup/royalliver
/usr/local/backup/ure_andras
/usr/local/backup/profserv
/usr/local/backup/frontoffice
/usr/local/backup/ure.orig
/usr/local/backup/projectcommon
/usr/local/backup/playground
/usr/local/backup/casegen

I'm pretty much stuck at this point. Can anyone help me out here? Thanks in advance, Dave

A: 

put a cut command at the end

find /usr/local/svn/repos/ -maxdepth 1 -mindepth 1 -type d -exec echo /usr/local/backup{} \| cut -f1,2,3,9 -d"/"
Vijay Sarathi
A: 

How about adding a sed filter cuting out the middle part?

sed 's/usr.local.svn.repos.//g'

Added like this

find /usr/local/svn/repos/ -maxdepth 1 -mindepth 1 -type d -exec echo /usr/local/backup{} ";" | sed 's/usr.local.svn.repos.//g'
epatel
A: 
ls -al /usr/local/svn/repos/ |grep '^d' |sed s/^...............................................................//" |xargs -L 1 -I zzyggy echo /usr/local/svn/repos/zzyggy

It's a bit long but it does the trick. You don't have to do everything with find when there are lots of other shell commands, although if I had to write this kind of script, I would do it in Python and leave the shell for interactive work.

ls -al lists all the files in the named directory with attributes

grep '^d' selects the lines beginning with d which are directories

sed strips off all the characters to the left of the actual directory name. You may need to add or delete some dots

xargs takes the list of directory names and issues it one at a time. I specified zzyggy as the name to substitute in the executed command, but you can choose what you like. Of course, you would replace echo with your svnadmin command.

If it was in a shell script you should really do this

SVNDIRNAME="/usr/local/svn/repos"
ls -al $SVNDIRNAME |grep '^d' |sed s/^...............................................................//" |xargs -L 1 -I zzyggy echo $SVNDIRNAME/zzyggy

but I decided to show the wrong and right way just to explain this point. I'm going to tag this with some shell tag, but I still think that a Python script is a superior way to solve this kind of problem in the 21st century.

Michael Dillon
Speaking of "interactive work", `ls` was not really designed to do this kind of thing and `find` is perfectly suited for it. Also, perhaps your `sed` doesn't understand `'s/^.\{27\}//'`? (I didn't count your dots, so that's just a guess). And if you've **got** to parse `ls` like this, at least use `cut` instead of this ridiculous `sed` command. "I decided to show the wrong and right way" - Using a variable makes the difference? Sorry, but you've just bought yourself a 21st century downvote.
Dennis Williamson
Like I said, if I really had this job to do, I would write a Python script. Shell programming was OK in its day, but the quicker we all get over it, the better.
Michael Dillon
A: 

You were on the right track. Try this:

find /usr/local/svn/repos/ -maxdepth 1 -mindepth 1 -type d -printf "%f\0" | xargs -0 -I{} echo svnadmin hotcopy /usr/local/svn/repos/\{\} /usr/local/backup/\{\}

The %f is like basename and the null plus the -0 on xargs ensures that names with spaces, etc., get passed through successfully.

Just remove the echo and make any adjustments you might need and it should do the trick.

Dennis Williamson
I found this solution the perfect one. Thanks Dennis.
David Corley