Skip to content
Advertisement

Linux Bash find files on user input with multiple -name clauses

I am trying to create small utility to collect log files from remote host by creating tar ball, for simplicity assume for now assume to just display list of files based on user input.

This command works fine

find $LOGS_DIR -maxdepth 1 -type f ( -name 'process1.log*' -o -name  'process2.log*' ) -exec echo 'FOUND_FILES:{}' ';'

If i programmatically want to update -name clause based on the user input, say for example user input is process3.log*, process4.log*, process5*.log then my bash script should generate find command as

find $LOGS_DIR -maxdepth 1 -type f ( -name  'process3.log*'  -o -name  'process4.log*'  -o -name  'process5.log*' ) -exec echo 'FOUND_FILES:{}' ';'

Here is my snippet

...

for pattern in "${file_pattern_to_match[@]}"
do 
    if [ -z $final_pattern ];then
        final_pattern="-name $pattern"
        continue;
    fi
    final_pattern="$final_pattern -o -name $pattern"
done

#This will print final_pattern: -name  process3.log*  -o -name  process4.log* -o -name  process5.log*
echo "final_pattern:$final_pattern"

find $LOGS_DIR  -maxdepth 1   -type f  ( $final_pattern )  -exec echo "FOUND_FILES:{}"  ; 

But the issue is while executing the script find is evaluated as

find /x/path/logs  -maxdepth 1   -type f  ( -name process3.log.1 process3.log.2 -o -name process4.log.1 process4.log.2 )  -exec echo "FOUND_FILES:{}"  ; 

But the expected is

 find /x/path/logs  -maxdepth 1   -type f  ( -name "process3.log.*" -o -name process4.log.* -o -name process5.log.* )  -exec echo "FOUND_FILES:{}"  ; 

because the variable got expanded “find” is exiting with an error

Can someone please help me how to get the expected result above?

Advertisement

Answer

Use an array to keep each argument properly quoted.

first=
for pattern in "${file_pattern_to_match[@]}"
do 
    if [ -z "$first" ]; then
        final_pattern=(-name "$pattern")
        first=1
    else
        final_pattern+=(-o -name "$pattern")
    fi
done

# Hacky
# first=
# for pattern in "${file_pattern_to_match[@]}"
# do 
#   final_pattern+=($first -name "$pattern")
#   first=-o
# done

find "$LOGS_DIR"  -maxdepth 1 -type f  ( "${final_pattern[@]}" )  -exec echo "FOUND_FILES:{}"  ;
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement