grep 无法处理 for 循环中的文件名

Whi*_*Rau 1 linux grep bash

学习 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...条线。

我缺少什么?

ilk*_*chu 5

如果要匹配最后一个文件名部分中名为.../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设置了,则仅一个不匹配的项就足以使整个命令失败。