2
#!/bin/sh
checking()
{
  cd "$1"
  for D in *;do
    if [ -d "$D" ]; then
      cd "$D"
      for d in *;do
        echo "$d"
        if [ -d "$d" ]
        then
           `checking() $d`
        fi
        if [ -f "$d" ]
        then
                file_name=`echo "$d" | cut -d'.' -f1`
                echo $file_name
                file_ext=$(echo $d |awk -F . '{if (NF>1) {print $NF}}')
                echo $file_ext
                if [ $file_ext = bin ]
                then
                        strings $d > $file_name.txt
                        mv $file_name.txt /somepath
                fi
        fi

      done
      cd ..

    fi
  done
}

a=$(pwd)
checking() $a

I am converting session log binary files into text files and storing on some path using strings function. For every directory it is performing fine,but it is not checking the binary files for any sub directory present.

I tried using recursive function call but that call is not being fired..Please help

1
  • 3
    Well, for one, shell functions act like any other commands, so you'd call a function hello with something like hello arg1 arg2. Bash actually gives you an error message for something() $a, dash crashed when I tried that...
    – ilkkachu
    Commented Nov 29, 2017 at 10:18

1 Answer 1

4

I note a couple of things in your function:

  • You change into a directory, then iterate over the files, then do both again (cd; for d in *; do cd; for d in * ...). This seems like it would skip every other level of the directory tree during a recursive walk. One iteration over the files should be enough
  • I don't think you need to use a subshell when recursively calling the function (there's the backtick command substitution in `checking() $d`). That could be useful if you needed variables local to each instance of the function call, but many shells can do that directly (using local in Bash, apparently typeset in ksh93)
  • And of course the syntax for calling a function: given hi() { echo "hello $1"; } we run it like any other command, simply with hi "$name".
  • We can nix the awk and use the shell's parameter expansion to pick the file extension. (but do check the borderline case when there is no dot in the filename.) Or use case "$f" in *.bin) ...

Here's a rather simple function for walking a directory tree:

#!/bin/sh

walk() {
        cd "$1"
        for f in *; do 
                if [ -d "$f" ] ; then
                        echo descending into "$f"...
                        walk "$f"
                else
                        ext=${f##*.}
                        if [ "$ext" = "bin" ] ; then
                                echo "found .bin file: $f"
                        fi
                fi

        done
        cd ..
}

walk .

(Though note that the cd "$dir"; ... ; cd .. structure can cause issues if someone moves a directory right at the moment the program is processing that directory. The .. link would change, and returning through it would continue from the new location, which might even be outside the original tree. We could work around that by using absolute path names all the time, or with pushd/popd (in Bash), or by putting the whole function or calls to it in subshells.)

2
  • 1
    Put the function body within (...) instead of {...} to get rid of the need for cd ...
    – Kusalananda
    Commented Nov 29, 2017 at 11:00
  • 1
    @Kusalananda, well, yeah, that's the subshell solution.
    – ilkkachu
    Commented Nov 29, 2017 at 11:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .