Bash comes with commands like basename (extracts filename out of a fullpath filename), and dirname (extracts the directory path out of a fullpath filename). However it doesn’t come with commands to extract the extension. You have to use other commands like cut, awk, rev, or even the bash built in variable tricks to extract the extension.
Sidenote: notice I surround the script with parenthesis, (), that is so a sub-shell is started for the script (anything inside the parenthesis)
Input:
( fullfile="/some/folder/text.txt" echo "INPUT fullfile:" echo $fullfile # Bash tricks echo "--- bash tricks ---" filename=$(basename "$fullfile") extension="${filename##*.}" filename0="${filename%.*}" echo "OUTPUT filename:" echo $filename echo "OUTPUT the extension:" echo $extension echo "OUTPUT filename with out extension:" echo $filename0 # Command Tricks echo "--- command tricks ---" echo "OUTPUT fullfile without extension:" echo $fullfile | rev | cut -d. -f2- | rev echo "OUTPUT the extension:" echo $fullfile | rev | cut -d. -f1 | rev echo $fullfile | awk -F. '{print $NF}' # sidenote: can select other fields with $(NF-1) etc, just change the 1 constant echo $fullfile | xargs -0 -I % basename % | awk -F. '{print $NF}' # this essentially just runs: basename $fullfile | awk -F. 'print $NF' # xargs is good to run for a list of things (like a list of files) echo "OUTPUT the extension with find:" find /var/log -type f -print0 | xargs -0 -I % basename % | awk -F. '{print $NF}' # -print0 on find so that files dont begin with new line or spaces, but with null char (which are not allowed in filenames, so its a good delimiter), this way files with spaces are correctly processed. likewise you need to catch it in xargs with -0, that way it knows each new file is delimited with a null char echo "OUTPUT list of all of the extensions:" find /var/log -type f -print0 | xargs -0 -I % basename % | awk -F. '{print $NF}' | sort | uniq -c # sort them, then count up the unique items next to each other with -c, which logically will give the count of all of the extensions (case sensitive) echo "--- the end ---" )
Output:
INPUT fullfile: /some/folder/text.txt --- bash tricks --- OUTPUT filename: text.txt OUTPUT the extension: txt OUTPUT filename with out extension: text --- command tricks --- OUTPUT fullfile without extension: /some/folder/text OUTPUT the extension: txt txt txt OUTPUT the extension with find: log log log 2 log managed journal journal journal journal smbd nmbd log log log log lastlog faillog wtmp btmp log log log log log err log OUTPUT list of all of the extensions: 1 2 1 btmp 1 err 1 faillog 4 journal 1 lastlog 14 log 1 managed 1 nmbd 1 smbd 1 wtmp --- the end ---
NOTE: files without extension just produce their filename
The end