Search code examples
bashdirectory-listing

List all the files with prefixes from a for loop using Bash


Here is a small[but complete] part of my bash script that finds and outputs all files in mydir if the have the prefix from a stored array. Strange thing I notice is that this script works perfectly if I take out the "-maxdepth 1 -name" from the script else it only gives me the files with the prefix of the first element in the array.

It would be of great help if someone explained this to me. Sorry in advance if there is some thing obviously silly that I'm doing. I'm relatively new to scripting.

#!/bin/sh
DIS_ARRAY=(A B C D)
echo "Array is : "
echo ${DIS_ARRAY[*]}
for dis in $DIS_ARRAY
do
    IN_FILES=`find /mydir  -maxdepth 1 -name "$dis*.xml"`
    for file in $IN_FILES
    do
    echo $file
    done
done

Output:

/mydir/Abc.xml
/mydir/Ab.xml
/mydir/Ac.xml

Expected Output:

/mydir/Abc.xml
/mydir/Ab.xml
/mydir/Ac.xml
/mydir/Bc.xml
/mydir/Cb.xml
/mydir/Dc.xml

Solution

  • The loop is broken either way. The reason why

    IN_FILES=`find mydir  -maxdepth 1 -name "$dis*.xml"`
    

    works, whereas

    IN_FILES=`find mydir "$dis*.xml"`
    

    doesn't is because in the first one, you have specified -name. In the second one, find is listing all the files in mydir. If you change the second one to

    IN_FILES=`find mydir -name "$dis*.xml"`
    

    you will see that the loop isn't working.

    As mentioned in the comments, the syntax that you are currently using $DIS_ARRAY will only give you the first element of the array.

    Try changing your loop to this:

    for dis in "${DIS_ARRAY[@]}"
    

    The double quotes around the expansion aren't strictly necessary in your specific case, but required if the elements in your array contained spaces, as demonstrated in the following test:

    #!/bin/bash
    
    arr=("a a" "b b")
    
    echo using '$arr'
    for i in $arr; do echo $i; done
    echo using '${arr[@]}'
    for i in ${arr[@]}; do echo $i; done
    echo using '"${arr[@]}"'
    for i in "${arr[@]}"; do echo $i; done
    

    output:

    using $arr
    a
    a
    using ${arr[@]}
    a
    a
    b
    b
    using "${arr[@]}"
    a a
    b b
    

    See this related question for further details.