Loop through files excluding directories

#!/bin/bash -

for file in "$dir"/*
do
  if [ ! -d "$file" ]; then
      "$@" "$file"
  fi
done

Note that it also excludes files that are of type symlink and where the symlink resolves to a file of type directory (which is probably what you want).

Alternative (from comments), check only for files:

for file in "$dir"/*
do
  if [ -f "$file" ]; then
      "$@" "$file"
  fi
done

Here's an alternative to using a for loop if what you need to do is simple (and doesn't involve setting variables in the main shell &c).

You can use find with -exec and use -maxdepth 1 to avoid recursing into the subdirectory.

[ -n "$1" ] && find "$dir" -type f -mindepth 1 -maxdepth 1 -exec "$@" "{}" \;

The [ -n "$1" ] is there to avoid executing all the files in the directory when the script isn't passed any arguments.


In zsh, you can use glob qualifiers to restrict wildcard matches by file type. For example, adding (.) after the pattern restricts it to regular files.

wc -w *(.)

To cope with file names beginning with - or ., use wc -c -- *(.N) or wc -c ./*(.N). If you want to include symbolic links to regular files as well, make that *(-.).

The other common shells have no such feature, so you need to use some different mechanism for filtering by file such as testing file types in a loop or find.

Tags:

Bash

For