Loop through files excluding directories
Solution 1
#!/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
Solution 2
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.
Solution 3
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
.
Related videos on Youtube
Tõnis Piip
Updated on September 18, 2022Comments
-
Tõnis Piip almost 2 years
I need my script to do something to every file in the current directory excluding any sub-directories.
For example, in the current path, there are 5 files, but 1 of them is a folder (a sub-directory). My script should activate a command given as arguments when running said script. I.e. "bash script wc -w" should give the word count of each file in the current directory, but not any of the folders, so that the output never has any of the "/sub/dir: Is a directory" lines.
My current script:
#!/bin/bash dir=`pwd` for file in $dir/* do $* $file done
I just need to exclude directories for the loop, but I don`t know how.
-
laktak over 7 years@roaima good idea!
-
JRFerguson over 7 yearsBetter to use
if [ -f "$file" ]; then ...
. Not a directory would return not only regular files but sockets and symlinks too. -
roaima over 7 years@JRFerguson based on the OP's question I would say that including sockets and pipes would be a really bad idea. As for symlinks, those are implicitly included with
! -d
already. -
Tõnis Piip over 7 yearsI used [ -f $file ] in my final script. Note the lack of quotation marks in the if condition. Almost everywhere I looked had quotation marks around $file, yet I had to delete them in order for my script to work.