Saturday, April 12, 2008

Stripping Down Filenames in Bash

I've seen these two questions asked multiple times and have both haunted me from time to time, so I thought I would provide some answers, although the second is rather rudimentary.

1. Stripping the path off of a file
How often have you needed only the filename, not the path that precedes it? Fortunately most Linux distros make it pretty easy to strip off with the basename command. E.g.,

user@host:~$ basename /etc/apache2/httpd.conf
httpd.conf


Note that if the path contains spaces you will need to enclose it in quotes or escape it:

#Escaping
user@host:~$ basename /home/madjon/youth\ room\ shots/local\ youth\ demographics.xls
local youth demographics.xls

#Quoting
user@host:~$ basename "/home/madjon/youth room shots/local youth demographics.xls"
local youth demographics.xls


2. Stripping the file extension
This takes some bash string manipulation which you can find all about at tldp. If we take httpd.conf again:

# First, assign the filename to a variable:
user@host:~$ f=/etc/apache2/httpd.conf
user@host:~$ echo $f
/etc/apache2/httpd.conf

#Next, strip out any string, starting from the end of $f that matches ".*"
user@host:~$ echo ${f%.*}
/etc/apache2/httpd


Note that the variable substitution (the curly brackets) doesn't have the $ inside it. E.g., the general syntax is:

VAR=whatever
echo ${VAR%.*}


If we want to put them together:

user@host:~$ f=/etc/apache2/httpd.conf
user@host:~$ f=`basename $f`
user@host:~$ echo $f
httpd.conf
user@host:~$ echo ${f%.*}
httpd


I'm sure that this could be accomplished easier with some regex and awk or sed, but all three of those are confusing to me; simple bash scripting makes much more sense to me. I hope this helps whomever.


No comments: