Linux
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...
條線。我錯過了什麼?
您的腳本在哪裡說:
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
)使用nullglob
set 不匹配的無關緊要,但是如果您failglob
設置了,則僅一個不匹配的就足以使整個命令失敗。