Working with filenames in bash

Bash has powerful shell parameter expansion capabilities, which we can use along with a couple of functions to deconstruct filenames.

To get the directory of a file, use dirname:

me@pc ~/tmp $ dirname /home/steph/tmp/test.txt
/home/steph/tmp

To get the name of a file, use basename:

me@pc ~/tmp $ basename /home/steph/tmp/test.txt
test.txt

With the use of basename, we can get a file’s root name and extension using Bash parameter expansion. If the file is test.txt then its root name is test and its extension is txt.

${parameter%word}
${parameter%%word}
${parameter#word}
${parameter##word}

If the file is $filename we have the following:

Expression Action Example
$(filename%.*} Get the root name of $filename, taking the last occurence of . as the end of the name, i.e. remove the shortest possible match of .* from the end of $filename. test.txt.gz -> test.txt
$(filename%%.*} Get the root name of $filename, taking the first occurence of . as the end of the name, i.e. remove the longest possible match of .* from the end of $filename. test.txt.gz -> test
$(filename#*.} Get the extension of $filename, taking the first occurence of . as the start of the extension, i.e. remove the shortest possible match of *. from the start of $filename. test.txt.gz -> .txt.gz
$(filename##*.} Get the extension of $filename, taking the last occurence of . as the start of the extension, i.e. remove the longest possible match of *. from the start of $filename. test.txt.gz -> .gz

The following script illustrates the above expansions using a filename provided to the script as an argument $1:

#!/bin/bash

filename=$(basename "$1")
echo
echo Long name, short extension
echo name: "${filename%.*}"
echo extension: "${filename##*.}"
echo
echo Short name, long extension
echo name: "${filename%%.*}"
echo extension: "${filename#*.}"
echo
me@pc ~/tmp $ ./parameter-expansion.sh one

Long name, short extension
name: one
extension: one

Short name, long extension
name: one
extension: one

me@pc ~/tmp $ ./parameter-expansion.sh one.two

Long name, short extension
name: one
extension: two

Short name, long extension
name: one
extension: two

me@pc ~/tmp $ ./parameter-expansion.sh one.two.three

Long name, short extension
name: one.two
extension: three

Short name, long extension
name: one
extension: two.three

References

Last modified: 24/03/2013 Tags:

This website is a personal resource. Nothing here is guaranteed correct or complete, so use at your own risk and try not to delete the Internet. -Stephan

Site Info

Privacy policy

Go to top