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

Leave a Reply

Your email address will not be published. Required fields are marked *