views:

639

answers:

5

I started with this:

command *

But it doesn't work when the directory is empty; the * wildcard becomes a literal "*" character. So I switched to this:

for i in *; do
   ...
done

which works, but again, not if the directory is empty. I resorted to using ls:

for i in `ls -A`

but of course, then file names with spaces in them get split. I tried tacking on the -Q switch:

for i in `ls -AQ`

which causes the names to still be split, only with a quote character at the beginning and ending of the name. Am I missing something obvious here, or is this harder than it ought it be?

+4  A: 

Assuming you only want to do something to files, the simple solution is to test if $i is a file:

for i in * 
do
    if test -f "$i" 
    then
       echo "Doing somthing to $i"
    fi
done

You should really always make such tests, because you almost certainly don't want to treat files and directories in the same way. Note the quotes around the "$i" which prevent problems with filenames containing spaces.

anon
This seems like the simplest answer. It's odd that so many shell scripting guides always tell you to use *, but don't always mention the literal "*" behavior when there are no files in the CWD.
+2  A: 

find could be what you want.

find . | while read file; do
    # do something with $file
done

Or maybe like this:

find . -exec <command> {} \;

If you do not want the search to include subdirectories you might need to add a combination of -type f and -maxdepth 1 to the find command. See the find man page for details.

Bombe
Added benefit of not breaking when you have 10.000+ files in a directory.
MSalters
+1  A: 

this should do the trick:

find -type d -print0 | xargs -n 1 -0 echo "your folder: {} !"
find -type f -print0 | xargs -n 1 -0 echo "your file: {} !"

the print0 / 0 are there to avoid problems with whitespace

Niko
you are really better off using find -type d -exec echo "your folder: {}" \;... xargs runs into issues if your path is too deep.
Kendall Helmstetter Gelner
A: 

Stupid Windows file names with spaces!

I'm going to get hammered (down voted) for this, but... my advice to coworkers regarding scripting: as soon as your script has "if" or "while", it's time to put aside "shell", and pick up "perl" :-(

I'm sure there's some masochistic way to make this work, but ouch. By the way, Bombe's find -exec solution needs to limit the depth, so subdirectories don't get picked up as well.

Roboprog
It sure seems that way.
All you need to do is doublequote the $i in my answer - I've updated it. The biggest advantage of shell scripts is that a shell is always available.
anon
A: 

It depends whether you're going to type this at a command prompt, and which command you're applying to the files.

If it's typed you could go with your second choice and substitute something harmless for the command. I like to use echo instead of mv or rm, for example.

Put it all on one line:

for i in * ; do command $i; done

When that works - or you can see where it fails, and whether it's harmless, you can press up-arrow, edit the command and try again.

pavium