Linux

grep 不適用於 for 循環中的文件名

  • November 3, 2021

學習 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...條線。

我錯過了什麼?

您的腳本在哪裡說:

 if grep -qF _AAC $file; then

這就是說,“如果命名文件的內容$file包含文字字元串_AAC,那麼……”執行then塊的內容。

如果您的意思是_AAC在由變數擴展產生的字元串中搜尋$file(即檢查 _AAC 是否出現在文件名本身中),那麼在 中bash,您需要編寫:

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

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

如果要匹配所有名為 like 的文件,.../something_AACxyz_AAC最後一個文件名部分中,只需將該_AAC部分直接添加到 glob 模式/萬用字元中:

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

大括號擴展產生多個不同的球體,而@(..)它只是一個球體。(即*.{foo,bar}與 相同*.foo *.bar)使用nullglobset 不匹配的無關緊要,但是如果您failglob設置了,則僅一個不匹配的就足以使整個命令失敗。

引用自:https://unix.stackexchange.com/questions/676063