I found a solution that gets pretty close to the simplicity of the tcsh filename modifiers. I wrote 4 functions and put them in .bashrc.
e() # the extension
E() # everything but the extension
t() # the tail - i.e. everything after the last /
T() # everything but the tail (head)
Definitions are at the end.
These functions can accept an argument like so:
f=foo/bar/my_image_file.0076.jpg
e $f
--> jpg
E $f
--> foo/bar/my_image_file.0076
or accept input from a pipe, which is the feature from tcsh that I really wanted:
echo $f|E|e
--> 0076
or of course, a combination:
T $f|t
--> bar
and it just dawned on me it will accept many files through the pipe:
ls foo/bar/
--> my_image_file.0075.jpg my_image_file.0076.jpg
ls foo/bar/ |E|e
--> 0075
--> 0076
Definitions:
#If there are no args, then assume input comes from a pipe.
function e(){
if [ $# -ne 0 ]; then
echo ${1##*.}
else
while read data; do
echo ${data##*.} ;
done
fi
}
function E(){
if [ $# -ne 0 ]; then
echo ${1%.*}
else
while read data; do
echo ${data%.*}
done
fi
}
function t(){
if [ $# -ne 0 ]; then
echo ${1##*/}
else
while read data; do
echo ${data##*/} ;
done
fi
}
function T(){
if [ $# -ne 0 ]; then
echo ${1%/*}
else
while read data; do
echo ${data%/*}
done
fi
}
t()
is similar tobasename
and yourT()
is similar todirname
. I'll post my version of those as edits to my answer. They handle some edge cases in the way that the actual utilities do. – Safety