up vote 4 down vote favorite
2
share [g+] share [fb]

Does any one have a template shell script for doing something with ls for a list of directory names and looping through each one and doing something?

I'm planning to do ls -1d */ to get the list of directory names.

link|improve this question

50% accept rate
feedback

4 Answers

up vote 4 down vote accepted

Just use a for..do..done loop:

for f in `ls`; do
  echo "File -> $f"
done

You can replace the ls with ls *.txt or any other command that returns a list (of files, directories, or anything for that matter), or actually replace it with a list (not a command that generates a list) by removing the quotes.

Within the do loop, you just refer to the loop variable with the dollar sign prefix (so $f in the above example). You can echo it or do anything else to it you want.

For example, to rename all the .xml files in the current directory to .txt:

for x in `ls *.xml`; do 
  t=`echo $x | sed 's/\.xml$/.txt/'`; 
  mv $x $t && echo "moved $x -> $t"
done
link|improve this answer
1  
What if the filename has a space in it? – Daniel A. White Aug 28 '09 at 17:17
I'm iterating all folders. – Daniel A. White Aug 28 '09 at 17:18
feedback

For files with spaces in you will have to make sure to quote the variable like:

 for i in $(ls); do echo "$i"; done;

or, you can change the input field separator (IFS) environment variable:

 IFS=$'\n';for file in $(ls); do echo $i; done

Finally, depending on what you're doing, you may not even need the ls:

 for i in *; do echo "$i"; done;
link|improve this answer
nice use of a subshell in the first example – Nerdling Aug 28 '09 at 18:46
feedback

If you have GNU Parallel http:// www.gnu.org/software/parallel/ installed you can do this:

ls | parallel echo {} is in this dir

To rename all .txt to .xml:

ls *.txt | parallel mv {} {.}.xml

Watch the intro video for GNU Parallel to learn more: http://www.youtube.com/watch?v=OpaiGYxkSuQ

link|improve this answer
feedback

This is how I do it, but there are probably more efficient ways.

ls > filelist.txt

while read filename; do echo filename: "$filename"; done < filelist.txt
link|improve this answer
2  
Stick to pipes in place of the file: >ls | while read i; do echo filename: $i; done – Nerdling Aug 28 '09 at 18:46
Cool. I should say that you can also use $EDITOR filelist.txt in between the two commands. Lots of stuff you can do in an editor that is easier than on the command line. Not relevant to this question, though. – TREE Aug 31 '09 at 18:45
feedback

Your Answer

 
or
required, but never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.