Reputation: 625
I'm having a bit of trouble with globs in Bash. For example:
echo *
This prints out all of the files and folders in the current directory. e.g. (file1 file2 folder1 folder2)
echo */
This prints out all of the folders with a / after the name. e.g. (folder1/ folder2/)
How can I glob for just the files? e.g. (file1 file2)
I know it could be done by parsing ls but also know that it is a bad idea. I tried using extended blobbing but couldn't get that to work either.
Upvotes: 12
Views: 23496
Reputation: 69
You can do what you want in bash like this:
shopt -s extglob
echo !(*/)
But note that what this actually does is match "not directory-likes."
It will still match dangling symlinks, symlinks pointing to not-directories, device nodes, fifos, etc.
It won't match symlinks pointing to directories, though.
If you want to iterate over normal files and nothing more, use find -maxdepth 1 -type f
.
The safe and robust way to use it goes like this:
find -maxdepth 1 -type f -print0 | while read -d $'\0' file; do
printf "%s\n" "$file"
done
Upvotes: 6
Reputation: 1746
My go to in this scenario is to use the find
command. I just had to use it, to find/replace dozens of instances in a given directory. I'm sure there are many other ways of skinning this cat, but the pure for
example above, isn't recursive.
for file in $( find path/to/dir -type f -name '*.js' );
do sed -ie 's#FIND#REPLACEMENT#g' "$file";
done
Upvotes: 2
Reputation: 785146
WIthout using any external utility you can try for loop
with glob support
:
for i in *; do [ -f "$i" ] && echo "$i"; done
Upvotes: 23
Reputation: 272497
I don't know if you can solve this with globbing, but you can certainly solve it with find:
find . -type f -maxdepth 1
Upvotes: 13