Bash
grep 模式 A 的文件,但排除模式 B 的文件
我想 grep 包含模式 A (iwant) 的文件,但我想排除包含模式 B (idontwant) 的文件。
例子:
read -p "...what are you looking for: " iwant read -p "...what should not be included: " idontwant iwant="blue car" idontwant="red car"
假設我有以下文件:
-rw-rw-r--. 1 terpentin terpentin 45 Jun 8 16:04 blue.car -rw-rw-r--. 1 terpentin terpentin 44 Jun 8 16:05 mixed.car -rw-rw-r--. 1 terpentin terpentin 40 Jun 8 16:04 red.car
find . -type f -print -exec cat {} \; ./mixed.car blue car red car blue car ./red.car red car red car red car ./blue.car blue car blue car blue car
結果怎麼可能只得到文件“./blue.car”?
原始內容包括數百個長文本文件,這使得盡可能節省資源非常重要。
採用
find . -type f ! -exec grep -q "$idontwant" {} ';' -exec grep -q "$iwant" {} ';' -print
或者
find . -type f -exec grep -q "$iwant" {} ';' ! -exec grep -q "$idontwant" {} ';' -print
- 命令中的術語(有時稱為“謂詞”)
find
被表徵為測試(例如,-type f
)和動作(例如,-delete
)。可能很難從手冊頁中找出-exec
既是 action又是 test的內容。所以,就像尋找 。-type f -mtime -30 -name '*.txt' -可讀 -size +5 *test 6* *test 7* *test 8* …
依次將搜尋範圍縮小到滿足所有條件(滿足所有指定測試)的文件,因此
尋找 。-exec *cmd 1* {} ';' -exec *cmd 2* {} ';' -exec *cmd 3* {} ';' …
查找所有命令都成功的文件。
- 任何
find
測試都可以通過在它前面加上 來否定(反轉)!
。因此find . ! -type d
可以找到普通文件、符號連結、命名管道、套接字和設備文件——除了目錄之外的所有內容。- 請注意,
! -exec grep …
不等於-exec grep -v …
.-exec grep -v …
將找到至少有一行不匹配的文件。! -exec grep …
將找到沒有行匹配的文件。-q
選項 to是官方的grep
同義詞--quiet
,但它也意味著快速。它不寫入任何輸出(可能除了錯誤消息,如適用),但它也會在找到匹配項後立即退出——它不會將每個文件都讀到最後以找到每個匹配項。(當然,如果文件不包含任何匹配項,則grep
必須完整讀取它才能確定。)- 所以(TL;DR)命令找到文件
grep -q "$iwant" *文件*
成功並且
grep -q "$idontwant"*文件*
失敗(因為我們在它前面加上
!
)。
- 這兩個命令在功能上是等效的,但可能具有不同的性能(即,可能需要不同的執行時間)。如果只有少數文件包含搜尋字元串,
尋找 。-type f -exec grep -q "$iwant" {} ';' !-exec grep -q "$idontwant" {} ';' -列印
會更快,因為這
grep "$iwant"
會消除大部分文件。如果許多文件包含這兩個字元串,則尋找 。-類型 f !-exec grep -q "$idontwant" {} ';' -exec grep -q "$iwant" {} ';' -列印
會更快,因為這
! grep "$idontwant"
會消除大部分文件。