grep 無法處理 for 迴圈中的檔名

grep 無法處理 for 迴圈中的檔名

學習 bash 腳本,我正在嘗試使用 for 循環中的嵌套 grep 來過濾結果:

sample filenames:
  this-file_AAC.txt
  this-other_file_AAAC.txt
  yep-a-file_AAC.nfo
  oops_another_one.reamde

這是腳本:

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

這個想法是任何包含的文件_AAC都將對其應用操作;在這種特定情況下,只需列印到標準輸出即可確認結果是否正確。

問題是:沒有任何東西可以超越if陳述。所以我錯過了我不知道什麼。唯一有效的就是這printf "input...條線。

我缺什麼?

答案1

如果要匹配最後一個文件名部分中名為.../something_AACxyz,的所有文件,只需將該部分直接添加到 glob 模式/通配符中:_AAC_AAC

for file in ./**/*_AAC*.{txt,reamde,nfo}; do

如果你希望檔案名稱_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

在這裡,您還可以獲得與 glob 匹配的文件,但沒有_AAC.


無論如何,在 Bash 上,您還可以啟用extglob並重寫模式,@(...|...)而不是使用大括號擴充:

for file in ./**/*_AAC*.@(txt|reamde|nfo); do

大括號擴展產生多個不同的 glob,而@(..)它只是一個單一的 glob。 (即*.{foo,bar}與 相同*.foo *.barnullglob使用 set 時,不匹配的項目並不重要,但如果您設定了failglob,則僅一個不匹配的項就足以使整個命令失敗。

答案2

你的腳本說:

  if grep -qF _AAC $file; then

它的意思是,「如果指定檔案的內容$file包含文字字串,_AAC那麼......」執行區塊的內容then

如果您的意思是_AAC在變數擴充產生的字串中進行搜尋$file(即檢查 _AAC 是否出現在檔案名稱本身中),那麼在 中bash,您需要編寫:

  if grep -qF _AAC <<< "$file"; then

或者,正如 @roaima 指出的那樣,您正在搜尋的文字字串可以包含在通配符文件規範中。

相關內容