【问题标题】:How to search for keywords in metadata across all files in a folder recursively?如何递归地在文件夹中的所有文件中搜索元数据中的关键字?
【发布时间】:2022-12-14 07:13:50
【问题描述】:
我需要从一个位置递归搜索所有子目录和文件,并打印出包含与我指定的任何关键字匹配的元数据的所有文件。
例如如果约翰·史密斯被列为作者你好.js在元数据中,我的关键词之一是'约翰'我想要脚本打印你好.js.
我认为解决方案可能是MDLS和grep但我没用过狂欢很久之前,所以我有点卡住了。
我尝试了以下命令,但这只会打印关键字所在的行'约翰'被发现。
mdls hello.js | grep john
提前致谢。
(作为参考,我使用的是 macOS。)
【问题讨论】:
标签:
bash
scripting
grep
metadata
mdls
【解决方案1】:
如您在问题中所示,将 mdls 的输出通过管道传输到 grep 不会继承文件名。以下脚本递归遍历所选目录中的文件,并检查其中一个属性是否与所需模式匹配(使用正则表达式)。如果是,则输出文件名。
#!/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
' "$pattern" "$file"
fi
done
您可以使用文字测试而不是正则表达式:
if [[ $attrib_value == *$pattern* ]]
为了使用globstar,你需要使用比 MacOS 默认安装版本更高的 Bash 版本。如果那不可能,那么您可以使用find,但在处理包含换行符的文件名时存在挑战。这个脚本负责这个。
#!/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
' "$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" "{}"'