0

I'm trying to do a simple bash script to do something in one of each file in a set of folders. Also I like to count how many files the script read, but when the script pass of the loop, the numerical variable is reseted.

The code I'm using is like that

#!/bin/bash
let AUX=0
find . -type "f" -name "*.mp3" | while read FILE; do
    ### DO SOMETHING with $FILE###
    let AUX=AUX+1
    echo $AUX
done
echo $AUX

I can see that AUX is counting inside the loop, but the last "echo" prints a 0, and the variable seems to be really reseted. My console output is like that

...
$ 865
$ 866
$ 867
$ 868
$ 0

I would like to preserve in AUX the number of files proccesed. Any idea?

APerson
  • 8,140
  • 8
  • 35
  • 49
  • 1
    This is BashFAQ #24: http://mywiki.wooledge.org/BashFAQ/024 – Charles Duffy Feb 27 '14 at 18:52
  • ...also, as a best-practices-related aside, it's safer to use lowercase for variable names which are neither exported to the environment or shell built-ins; that way you're safe from naming conflicts. – Charles Duffy Feb 27 '14 at 18:53

2 Answers2

4

Do not use the pipe, it creates a subshell. Example below.

#!/bin/bash
declare -i AUX=0
while IFS='' read -r -d '' file; do
    ### DO SOMETHING with $file###
    (( ++AUX ))
    echo $AUX
done < <(find . -type "f" -name "*.mp3")
echo $AUX
bobah
  • 18,364
  • 2
  • 37
  • 70
  • 2
    If you're trying to showcase best practices, I'd suggest `find ... -print0` and `while IFS='' read -r -d '' file`; that way the code works correctly with names containing newlines and backslash-escape sequences (which `read` without `-r` will interpret). – Charles Duffy Feb 27 '14 at 18:50
  • ...also, while it's harmless as long as `AUX` is a number, in general, `echo $AUX` is a bad idea -- if `AUX=*`, for instance, that would list files in the current directory. Better to `echo "$AUX"`. – Charles Duffy Feb 27 '14 at 18:54
0

If you have bash 4.0 or later, use the globstar option instead of find:

shopt -s globstar
aux=0
for f in **/*.mp3; do
    # Just in case there is a directory name ending in '.mp3'
    [[ -f $f ]] || continue
    # Do something with $f
    echo "$(( ++aux ))"
done
chepner
  • 497,756
  • 71
  • 530
  • 681