0

I need to search all subdirectories and files recursively from a location and print out any files that contains metadata matching any of my specified keywords.

e.g. If John Smith was listed as the author of hello.js in the metadata and one of my keywords was 'john' I would want the script to print hello.js.

I think the solution could be a combination of mdls and grep but I have not used bash much before so am a bit stuck.

I have tried the following command but this only prints the line the keyword is on if 'john' is found.

mdls hello.js | grep john

Thanks in advance.

(For reference I am using macOS.)

user2989759
  • 279
  • 1
  • 4
  • 14

1 Answers1

0

Piping the output of mdls into grep as you show in your question doesn't carry forward the filename. The following script iterates recursively over the files in the selected directory and checks to see if one of the attributes matches the desired pattern (using regex). If it does, the filename is output.

#!/bin/bash
shopt -s globstar    # expand ** recursively
shopt -s nocasematch # ignore case
pattern="john"
attrib=Author
for file in /Users/me/myfiles/**/*.js
do
    attrib_value=$(mdls -name "$attrib" "$file")
    if [[ $attrib_value =~ $pattern ]]
    then
        printf 'Pattern: %s found in file $file\n' "$pattern" "$file"
    fi
done

You can use a literal test instead of a regular expression:

if [[ $attrib_value == *$pattern* ]]

In order to use globstar you will need to use a later version of Bash than the one installed by default in MacOS. If that's not possible then you can use find, but there are challenges in dealing with filenames that contain newlines. This script takes care of that.

#!/bin/bash
shopt -s nocasematch # ignore case
dir=/Users/me/myfiles/
check_file () {
    local attrib=$1
    local pattern=$2
    local file=$3
    local attrib_value=$(mdls -name "$attrib" "$file")
    if [[ $attrib_value =~ $pattern ]]
    then
        printf 'Pattern: %s found in file $file\n' "$pattern" "$file"
    fi
}
export -f check_file
pattern="john"
attrib=Author
find "$dir" -name '*.js' -print0 | xargs -0 -I {} bash -c 'check_file "$attrib" "$pattern" "{}"'
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439