How to check the extension of a filename in a bash script?

BashScriptingFile

Bash Problem Overview


I am writing a nightly build script in bash.
Everything is fine and dandy except for one little snag:


#!/bin/bash




for file in "$PATH_TO_SOMEWHERE"; do
if [ -d $file ]
then
# do something directory-ish
else
if [ "$file" == "*.txt" ]       #  this is the snag
then
# do something txt-ish
fi
fi
done;

for file in "$PATH_TO_SOMEWHERE"; do if [ -d $file ] then # do something directory-ish else if [ "$file" == "*.txt" ] # this is the snag then # do something txt-ish fi fi done;

My problem is determining the file extension and then acting accordingly. I know the issue is in the if-statement, testing for a txt file.

How can I determine if a file has a .txt suffix?

Bash Solutions


Solution 1 - Bash

Make

if [ "$file" == "*.txt" ]

like this:

if [[ $file == *.txt ]]

That is, double brackets and no quotes.

The right side of == is a shell pattern. If you need a regular expression, use =~ then.

Solution 2 - Bash

I think you want to say "Are the last four characters of $file equal to .txt?" If so, you can use the following:

if [ "${file: -4}" == ".txt" ]

Note that the space between file: and -4 is required, as the ':-' modifier means something different.

Solution 3 - Bash

You could also do:

   if [ "${FILE##*.}" = "txt" ]; then
       # operation for txt files here
   fi

Solution 4 - Bash

You just can't be sure on a Unix system, that a .txt file truly is a text file. Your best bet is to use "file". Maybe try using:

file -ib "$file"

Then you can use a list of MIME types to match against or parse the first part of the MIME where you get stuff like "text", "application", etc.

Solution 5 - Bash

You can use the "file" command if you actually want to find out information about the file rather than rely on the extensions.

If you feel comfortable with using the extension you can use grep to see if it matches.

Solution 6 - Bash

The correct answer on how to take the extension available in a filename in linux is:

${filename##*\.} 

Example of printing all file extensions in a directory

for fname in $(find . -maxdepth 1 -type f) # only regular file in the current dir
    do  echo ${fname##*\.} #print extensions 
done

Solution 7 - Bash

Similar to 'file', use the slightly simpler 'mimetype -b' which will work no matter the file extension.

if [ $(mimetype -b "$MyFile") == "text/plain" ]
then
  echo "this is a text file"
fi

Edit: you may need to install libfile-mimeinfo-perl on your system if mimetype is not available

Solution 8 - Bash

I wrote a bash script that looks at the type of a file then copies it to a location, I use it to look through the videos I've watched online from my firefox cache:

#!/bin/bash
# flvcache script

CACHE=~/.mozilla/firefox/xxxxxxxx.default/Cache
OUTPUTDIR=~/Videos/flvs
MINFILESIZE=2M

for f in `find $CACHE -size +$MINFILESIZE`
do
    a=$(file $f | cut -f2 -d ' ')
    o=$(basename $f)
    if [ "$a" = "Macromedia" ]
        then
            cp "$f" "$OUTPUTDIR/$o"
    fi
done

nautilus  "$OUTPUTDIR"&

It uses similar ideas to those presented here, hope this is helpful to someone.

Solution 9 - Bash

I guess that '$PATH_TO_SOMEWHERE'is something like '<directory>/*'.

In this case, I would change the code to:

find <directory> -maxdepth 1 -type d -exec ... \;
find <directory> -maxdepth 1 -type f -name "*.txt" -exec ... \;

If you want to do something more complicated with the directory and text file names, you could:

find <directory> -maxdepth 1 -type d | while read dir; do echo $dir; ...; done
find <directory> -maxdepth 1 -type f -name "*.txt" | while read txtfile; do echo $txtfile; ...; done

If you have spaces in your file names, you could:

find <directory> -maxdepth 1 -type d | xargs ...
find <directory> -maxdepth 1 -type f -name "*.txt" | xargs ...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiontheman_on_vistaView Question on Stackoverflow
Solution 1 - Bashuser49586View Answer on Stackoverflow
Solution 2 - BashPaul StephensonView Answer on Stackoverflow
Solution 3 - BashkvzView Answer on Stackoverflow
Solution 4 - BashEldelshellView Answer on Stackoverflow
Solution 5 - BashAdam PeckView Answer on Stackoverflow
Solution 6 - BashAlbin. Com.View Answer on Stackoverflow
Solution 7 - BashdargaudView Answer on Stackoverflow
Solution 8 - BashdesdecodeView Answer on Stackoverflow
Solution 9 - Bashjfg956View Answer on Stackoverflow