Bash File Loops

Some examples of iterating through files and looping through file content in Bash. For details, see the Bash man page or the Bash reference manual.

Loop Through Files

for FILE in *; do
  # do something with $FILE
  echo "File: $FILE"
done

For more control, use /usr/bin/file

for FILE in $(find ./ -name *.html -type f); do
  # do something with $FILE
  echo "HTML File: $FILE"
done

Loop Through Lines in a File

while read LINE; do
  # do something with $LINE
  echo "Line: $LINE"
done < /etc/hosts

Loop Through Words in a File

for WORD in $(cat /etc/hosts); do
  # do something with $WORD
  echo "Word: $WORD"
done

Loop Through Characters in a File

while read -n1 CHAR; do
  # do something with $CHAR
  echo "Character: $CHAR"
done < /etc/hosts


Comments

I think there is a typo: >

I think there is a typo:

> For more control, use /usr/bin/file

should be:

> For more control, use /usr/bin/find

Consider using find and

Consider using find and xargs for doing something across a group of files without risking breaking your script because you're operating on too many files (shell wildcard expansion has limits). Using GNU find and xargs:

find . -name '*.foo' -type f -print0 | xargs -0I {} ~/bin/my-script '{}'

will run "/bin/my-script" on all files (-type f) whose name ends in ".foo" in the current working directory (the dot after the find command) and every directory therein (find is recursive unless you tell it not to be). When you make /bin/my-script all you need to do is describe how to process one file.

find will normally print the list of matching files with a newline. Here we tell find to use NULLs to terminate each list entry (-print0) you can handle pathnames with spaces and other characters that break most scripts. The -0 tells xargs what to use to know where each filename ends. Just don't forget to quote properly in your script (called /bin/my-script here) so the complete pathname is preserved.

I'm also telling xargs where each filename is in the command (-I {} says to use the open/close curly brace as a placeholder for the pathname). This is optional if the last argument to the command is the pathname.

If you have files or

If you have files or directories that have spaces in them, one way to loop over them is with read:

ls * | while read X; do echo cp -p $X ${X}.bak; done

Cheers,
Jeff McCune

That is a very useful hint,

That is a very useful hint, Jeff. Thank you for it!
Peter