tags:

views:

45

answers:

3

I'm trying to use a for loop to get the filenames of files that end in .cpp.

Code:

for cppfile in ls *.cpp ; do 
echo $cppfile
done

I plan on doing more than just echoing the argument, but as it stands now, it works fine except that I'l get the command as the first arguement. Is there an easy way to avoid this, or will I have to do the loop in another fashion?

+5  A: 

You're not executing ls *.cpp there. What you're doing is iterating over "ls" followed by all the files that match "*.cpp". Removing the stray "ls" will fix this.

Ignacio Vazquez-Abrams
ok. I am still getting used to shell scripting and did not realize you didn't need to use ls. thanks
kevin
+3  A: 

As Ignacio said, you're not executing ls, your list is made up of ls and *.cpp, which gets expanded to all the files ending in .cpp. If you want to use the output of a command as a list, enclose it in backticks:

for cppfile in `ls *.cpp`
do
    echo $cppfile
done

In bash, you can use $(...) instead of backticks:

for cppfile in $(ls *.cpp)
do
    echo $cppfile
done

$(...) has an advantage that it nests better, but backticks are more portable.

Alok
thanks. Noted and appreciated
kevin
@kevin: Also note that you should *not* be using ls in this context. Files with spaces will cause no end of trouble with this.
Ignacio Vazquez-Abrams
@Ignacio: Agreed, and thanks clarification.
Alok
A: 
find ./ -name "*.cpp" | while read cppfile; do
  echo $cppfile
  #...
done
Dyno Fu
This is better than using ls, but it also has a couple of problems. The biggest is that the pipe will cause the loop to run in a subshell which means that variables created within will not exist outside of the loop. The second is that filenames with newlines (no, you're not likely to run into any, ever, but this is still of note) will cause issues. The third is that `find` is recursive by default; this will show all files matching `*.cpp` anywhere under the current directory. And of course there's the fact that the variable in echo is not quoted, but that's a separate issue.
Ignacio Vazquez-Abrams