Subversion (SVN) helper bash script to list repo dirs

Finding my way around SVN. So far I’ve created a repository to hold my WordPress theme files and miscellaneous scripts. The working directories are scattered around my home dir, and I found that I wanted a way to view the structure of the repo itself. You can do this with the svn list command:
svn list --recursive file:///path/to/your/svn/repo/dir
And you’ll get a list of all your directories and files. I thought it might be nice to only see the dirs, and then furthernice to specify the depth of dirs to browse, so I cobbled together the bash script below to accomplish this. It takes the output from svn list -R and prints only items that end with a forward slash, e.g.:
svn list -R file:///home/scarpent/src/svn | svn-dirs.sh -d 2
To produce the output:
bash/ bash/nautilus-scripts/ home-bin/ web/ web/mtf/

(I also created a script that runs svn list on my local repo and pipes to svn-dirs.sh, so I don’t have to type in the file:/// URL every time.)
How does it work?
First we use getopts to parse the command line options, which in this case is only -d, which lets us specify the max depth of directories we want to list.
Next, we use read to read the output produced by svn list. (Which becomes standard in — stdin — for our script.)
I initially thought of using the bash -d test to see if an item was a file or a dir, but I quickly realized that this wouldn’t work because these aren’t real files and directories. They’re part of the virtual SVN file system. Instead, I went by the last character, which is a forward slash for directories. We use ${#inpt} to get the length of the string, $(($len - 1)) to subtract one from that length, giving us the index of the last character, and then ${inpt:$last_char_idx} to extract that last character so we can compare it to “/”.
Finally, we determine how many slashes there are in the path — and thus the depth — by using this peculiar statement:
num_slashes=$(echo $inpt | tr -cd "/" | wc -c)
Which sends the SVN path in to the translate program, using options to discard anything that isn’t a forward slash, and then counts the remaining slashes with the word count program. (I found this neat trick in the Advanced Bash-Scripting Guide, along with a lot of other interesting string handling techniques. See resources below for more…)
And now, the script!
svn-dirs.sh script
#!/bin/bash # svn-dirs.sh # public domain script # by Scott Carpenter, 2007 usage="svn-dirs.sh [-d] specify the depth of dirs to list" max_depth=99 while getopts ":d:" opt do case $opt in d ) max_depth=$OPTARG ;; \? ) echo -e $usage exit 1 esac done shift $(($OPTIND - 1)) if [[ $(($max_depth < 1)) -eq 1 ]]; then max_depth=1 fi while read inpt do len=${#inpt} last_char_idx=$(($len - 1)) last_char=${inpt:$last_char_idx} # tr = translate, discarding non-matches # then use wc to count chars, giving us # the number of slashes num_slashes=$(echo $inpt | tr -cd "/" | wc -c) if [[ "$last_char" = "/" && $(($num_slashes <= $max_depth)) -eq 1 ]]; then echo "$inpt" fi done
And that’s that. I hope you find this useful for browsing your SVN repository and getting an overview of what you have stashed away in there.
Resources
-
Version Control with Subversion is an excellent O’Reilly book by Ben Collins-Sussman, Brian W. Fitzpatrick, and C. Michael Pilato. There is a free version online, or you can click on one of the Amazon links here if you want to buy a hard copy and cut me in on a share of the loot.
-
Learning the bash Shell is another good O’Reilly book by Cameron Newham and Bill Rosenblatt. Even with all the good bash info available for free on the Net, I still like to have books like this to guide me through things. Again if you buy through one of my Amazon links, I’ll get a small kickback on the purchase price.
-
The Advanced Bash-Scripting Guide by Mendel Cooper is one of those great free resources. The tag line is “An in-depth exploration of the art of shell scripting,” and it appears to be full of useful knowledge and techniques.
Related: SVN Nautilus Script Helpers
Posted by Scott Carpenter on 14 October 2007 at 8:28 am
filed under bash, source control, svn
Comments
-
Unix scripting is interesting in that there are many solutions to the same problem. Solutions come from perspective. I would have used awk to solve the same problem. Others would have used perl. Within bash, there are ways to solve this without calling external executables, such as wc or tr. Here’s what I would have done:
svn list -R file:///home/scarpent/src/svn |awk -F/ '$NF ~ /^$/ && NF <= 2'
awk is kind of like perl-lite. It is useful for parsing lines into fields at a separator. In this example, “/” is the separator. awk places the stuff between the separators into fields, which are addressable as $1, $2, etc. The number of fields is in the variable NF, and the contents of the last field are in $NF.
So, the awk statement parses the line (record in awk parlance) into fields at “/”, then for records that have no contents in the last field (i.e. the ones with a trailing “/”), and have a number of fields less than or equal to 2, print the line. The print is implied.
If you want to vary the number of fields to match, you can pass variables into awk using the -v switch:
svn list -R file:///home/scarpent/src/svn |awk -v NUM=2 -F/ '$NF ~ /^$/ && NF <= NUM'
which might make it more suitable for putting into a shell script.Posted by Mario Stargard on 15 October 2007 at 10:10 am
-
This may be premature optimization in this case, but in Bash you can use arithmetic inside parameter expansion. This can be used to get the last character in a variable, which you did in three steps.
${inpt:${#inpt}-1}This expands into the last character of
inptusing only one parameter expansion. As a bonus (?), it makes the code almost as unreadable as Perl. :)Posted by Christopher on 21 February 2008 at 5:10 pm
You can follow any responses to this entry through the
comments feed.



bookmark with del.icio.us
Richard Stallman:


