Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading files in order in BASH script

So I've got a bash script that greps a series of subdirectories, looking for files that contain a certain string, and then printing file totals and directory totals for the string's occurences. The code is as follows.

  for dir in $(find * -type d); do
  echo "directory: $dir" >> $OUT
  for f in $(find $dir/* -type f); do
    echo -n "$(basename $f) " >> $OUT
    grep -c -h $1 $f >> $OUT
  done
  echo -n "directory total: " >> $OUT
  grep -c -h $1 $dir/*.* | awk '{SUM += $1} END {print SUM}' >> $OUT
  done

When it does this, if I read in 10 files, it lists them in the text file as file1.txt, file10.txt, file2.txt etc...

Is there any way I could make it print file1.txt, file2.txt, file3.txt etc and have the 10th file be actually listed in order?

I'm new to BASH so I was just wondering if any knew anything about this. Any help greatly appreciated. And yes, the files are literally named file1.txt, file2.txt etc. This is mostly just to familiarize myself with BASH scripting.

like image 555
Robert Kelly Avatar asked May 22 '26 16:05

Robert Kelly


1 Answers

find -type d | while read -r dir
do
    echo "directory: $dir"
    find "$dir" -maxdepth 1 -type f | sort --version-sort | while read -r f
    do
        echo -n "$(basename "$f") "
        grep -c -h "$1" "$f"
    done
    grep -c -h "$1" "$dir/*" | awk -F: '{SUM += $1} END {print "directory total:", SUM}'
done > "$OUT"
  • Move the redirection to the end of the loop
  • Use while read instead of for in case filenames include spaces (additional measures can be taken to protect against some less common odd characters if needed)
  • Quote your variables also to protect white space
  • Use -maxdepth 1 with the inner find to avoid overlapping duplication
  • Use sort --version-sort to get the filenames in the order you want
  • AWK can print the text at the same time it prints the total
  • The field separator needs to be set to a colon
  • Instead of echo -n "$(basename "$f") " you could use echo -n "${f##*/} "
like image 134
Dennis Williamson Avatar answered May 24 '26 22:05

Dennis Williamson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!