34

In a directory you have some various files - .txt, .sh and then plan files without a .foo modifier.

If you ls the directory:

blah.txt
blah.sh
blah
blahs

How do I tell a for-loop to only use files without a .foo modify? So "do stuff" on files blah and blahs in the above example.

The basic syntax is:

#!/bin/bash
FILES=/home/shep/Desktop/test/*

for f in $FILES
do
    XYZ functions
done

As you can see this effectively loops over everything in the directory. How can I exclude the .sh, .txt or any other modifier?

I have been playing with some if statements but I am really curious if I can select for those non modified files.

Also could someone tell me the proper jargon for these plain text files without .txt?

3 Answers 3

44
#!/bin/bash
FILES=/home/shep/Desktop/test/*

for f in $FILES
do
if [[ "$f" != *\.* ]]
then
  DO STUFF
fi
done
Sign up to request clarification or add additional context in comments.

4 Comments

This works for me in a modified form. Some of my file names contain ".'s" so using \. can still select them. What is fi used for n your code? Thank you!
It's just the endif for bash (if backwards).
hmm that would be why 'done' threw an error, needed to close the if statement. Cool thanks.
It would be much more helpful if you added an explanation as to why this is a solution to OP's question.
14

If you want it a little bit more complex, you can use the find-command.

For the current directory:

for i in `find . -type f -regex \.\\/[A-Za-z0-9]*`
do
WHAT U WANT DONE
done

explanation:

find . -> starts find in the current dir
-type f -> find only files
-regex -> use a regular expression
\.\\/[A-Za-z0-9]* -> thats the expression, this matches all files which starts with ./
(because we start in the current dir all files starts with this) and has only chars
and numbers in the filename.

http://infofreund.de/bash-loop-through-files/

Comments

4

You can use negative wildcards? to filter them out:

$ ls -1
a.txt
b.txt
c.png
d.py
$ ls -1 !(*.txt)
c.png
d.py
$ ls -1 !(*.txt|*.py)
c.png

5 Comments

Ok, but say I have a directory with more than two of them. Is there a logical way to make bash do this for me? So that it can be applied on most directories while working the same way.
@jon_shep: More than two of what?
file extensions. In your example you had to manually exclude them.
!(*.*), and no, this is not POSIX.
You also need to set the extglob option for this to work: shopt -s extglob.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.