views:

5634

answers:

5

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;

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?

+9  A: 

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.

Adam Peck
yes I am aware of the `file` command. I had actually tried matching based on the output of said command... but I fail horribly at these if-statements.
+9  A: 

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.

Paul Stephenson
Kind of hacky, but it works! I am slightly worried because in Linux, giving a file extension of .txt doesnt make it a text file... but i think it should be fine. Thanks a lot
to that end, you can rename command.com to command.txt on a windows machine too.
hometoast
+5  A: 

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.

Ubersoldat
+5  A: 

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.

Georgi Kirilov
I didn't know about this. It seems to be a special case that the right-hand side of == or != is expanded as a shell pattern. Personally I think this is clearer than my answer.
Paul Stephenson
+1  A: 

I don't know if the "file" command is standard on most Unix systems. I had to install it from ports last night on a fresh install of FreeBSD 7.0 and on my Solaris10 server at work the file command is found in in the /usr/ucb addons directory. So it is possible that it might not be available.

I think the safest solution to this is still string manipulation in the script as Paul pointed out.

tmeisenh
file is pretty standard. it is great because it actually examines the file and makes it best guess at what the file actually is. example - renaming bewbz.jpg to bewbz.txt and then doing `file bewbz.txt`, it will say its a jpeg image