user201535 user201535 - 1 year ago 42
Bash Question

How to check for specific file types in an if statement with bash shell

I want to know how I would go about looking for..let's say text files in a given directory. I want to iterate through all of the files in my directory, and for every text file, I want to convert it to a pdf file. Problem is, I do not know how to check whether a file is a text file within the parameters of an if statement in bash shell.

I set my

ListOfFiles = `ls -l`

and I iterate through with a
for
loop, i just need to know how to check for file types in an
if
statement.

Thank you in advance.

Answer Source

The following lists all text files in the current directory.

file --mime-type * -F$'\t' | awk -F'\t *' '$2 ~/^text\/plain/ { print $1 }'

Note: This assumes that your filenames have neither embedded tabs nor embedded newlines, which is not typically a problem.

  • file --mime-type * -F$'\t' determines the file type of each file in the current folder (*) and prints a two-column list: the filename at hand, followed by a tab (-F'$\t'), followed by spaces for alignment, followed by the file type expressed as a MIME type.

  • awk -F'\t *' '$2 ~/^text\/plain/ { print $1 }' then parses each line into the filename and MIME type (-F'\t *), tests if the MIME type (field 2,$2) starts with (^) string text/plain and, if so, prints the filename (field 1, $1).

To process the resulting files in a loop, use while:

while IFS= read -r textfile; do
  # Work with "$textfile"
done < <(file --mime-type * -F$'\t' | awk -F'\t *' '$2 ~/^text\/plain/ { print $1 }')

Note that while you could call file in a conditional inside a for file in * loop, the above approach is much more efficient.
For the record, here's how you would use the command in a conditional:

if [[ $(file -b --mime-type "$file") == 'text/plain'* ]]; then ...