4

What's the best way to print all the files listed in a directory and the numer of files using a for loop? Is there a better of doing this?

#!/bin/bash

target="/home/personal/scripts/07_22_13/ford/$1"

for file in "$target"/*
do
  printf "%s\n" "$file" | cut -d"/" -f8
done
theGrayFox
  • 891
  • 1
  • 10
  • 18
  • 1
    Note that the script does not know the `$HOME` var, so you have to use `/home...`. – fedorqui 'SO stop harming' Jul 22 '13 at 14:48
  • Is there a way to perhaps not have to include the entire path? That would definitely make it easier on the user. @fedorqui – theGrayFox Jul 22 '13 at 14:50
  • Mmm maybe you can define an initial path structure like `path=/home/this_user` and then check `$path/$directory`. – fedorqui 'SO stop harming' Jul 22 '13 at 14:51
  • 1
    what exactly is the problem? how is your script related to the question in the subject? – umläute Jul 22 '13 at 14:54
  • http://stackoverflow.com/a/1978230/489590 walks a tree, so your question is a special case that should be answered by it. – Brian Cain Jul 22 '13 at 14:56
  • Okay, I see what you're saying. It's like assigning a halfway path to a variable that way the user only has to worry about the name of the directory. – theGrayFox Jul 22 '13 at 14:56
  • @umläute I couldn't figure out why the script wasn't finding the given directory until I realized what fedorqui had stated about having to declare the full path. Other than that I wanted to know the best way of looping through a directory and printing all of the files contained inside. – theGrayFox Jul 22 '13 at 15:02
  • I've re-edited the post. @umläute – theGrayFox Jul 22 '13 at 15:26

2 Answers2

7

Here is a solution:

#!/bin/bash

target="/home/personal/scripts/07_22_13/ford/$1"
let count=0
for f in "$target"/*
do
    echo $(basename $f)
    let count=count+1
done
echo ""
echo "Count: $count"

Solution 2

If you don't want to deal with parsing the path to get just the file names, another solution is to cd into the directory in question, do your business, and cd back to where you were:

#!/bin/bash

target="/home/personal/scripts/07_22_13/ford/$1"
pushd "$target" > /dev/null
let count=0
for f in *
do
    echo $f
    let count=count+1
done
popd
echo ""
echo "Count: $count"

The pushd and popd commands will switch to a directory, then return.

Hai Vu
  • 30,982
  • 9
  • 52
  • 84
  • What would you use to format the output of the files to just see the file names? I ended up using cut, but what would you suggest? – theGrayFox Jul 22 '13 at 15:45
  • I came up with this: awk -F '/' '{ print $8 | "sort" }' I'll look at basename in just a second. – theGrayFox Jul 22 '13 at 17:27
  • I like basename, I figured something else out as well. You could also do something like: echo ${f##*/} | sort – theGrayFox Jul 22 '13 at 17:52
0
target="/home/personal/scripts/07_22_13/ford/$1"
for f in "$target"/*; do
    basename "$f"
done | awk 'END { printf("File count: %d", NR); } NF=NF'

basename "$f" will automatically output each filename on its own line, and the awk code will print the total number of records processed, which is this case is the number of files listed. Additionally, awk will automatically print the filenames because of the NF=NF pattern at the end. I'd say learning awk can be advantageous, as shown here. :-)