学习 bash 脚本,我正在尝试使用 for 循环中的嵌套 grep 来过滤结果:
sample filenames:
this-file_AAC.txt
this-other_file_AAAC.txt
yep-a-file_AAC.nfo
oops_another_one.reamde
Run Code Online (Sandbox Code Playgroud)
这是脚本:
shopt -s globstar nullglob dotglob
for file in ./**/*.{txt,reamde,nfo}; do
printf "input: ${file}\n"
if grep -qF _AAC $file; then
printf "output: ${file}\n"
# do stuff with $file
fi
done
Run Code Online (Sandbox Code Playgroud)
这个想法是任何包含的文件都_AAC将对其应用操作;在这种特定情况下,只需打印到标准输出即可确认结果是否正确。
问题是:没有什么可以超越if陈述。所以我错过了我不知道什么。唯一有效的就是这printf "input...条线。
我缺少什么?
如果要匹配最后一个文件名部分中名为.../something_AACxyz,的所有文件,只需将该部分直接添加到 glob 模式/通配符中:_AAC_AAC
for file in ./**/*_AAC*.{txt,reamde,nfo}; do
Run Code Online (Sandbox Code Playgroud)
如果你希望文件名_AAC可以出现在任何部分,你可以这样做(在 Bash 中):
for file in ./**/*.{txt,reamde,nfo}; do
if [[ $file == *_AAC* ]]; then
echo "'$file' contains _AAC"
else
echo "'$file' has NO _AAC"
fi
done
Run Code Online (Sandbox Code Playgroud)
在这里,您还可以获得与 glob 匹配的文件,但没有_AAC.
无论如何,在 Bash 上,您还可以启用extglob并重写模式,而@(...|...)不是使用大括号扩展:
for file in ./**/*_AAC*.@(txt|reamde|nfo); do
Run Code Online (Sandbox Code Playgroud)
大括号扩展产生多个不同的 glob,而@(..)它只是一个单一的 glob。(即*.{foo,bar}与 相同*.foo *.bar)使用nullglobset 时,不匹配的项并不重要,但如果您failglob设置了,则仅一个不匹配的项就足以使整个命令失败。