在腳本中,我想尋找包含一些文字的檔案。我grep
需要知道在其中找到文字的文件,以及在其中找到文字的文件中的整行:
。是否有某種我可以使用的--porcelain
模式grep
,就像git
指令經常使用的模式?
範例:我有一個資料夾,裡面裝滿了test-num:1:date:jan-2
我想要 grep 的檔案。這些文件包含FAILURE:<some reason>
or SUCCESS:<some reason>
(以及其他內容)。我需要一個腳本來搜尋某些原因並儲存檔案名稱和原因(整行文字都可以)以供以後處理。輸出可以是任何類型的資料結構,只要我可以對其運行程式碼即可。
答案1
不存在諸如 之類的東西grep --porcelain
,在 UNIX 中,處理檔案名稱中的特殊字元始終是事後才想到的。您可以嘗試這樣的事情,但要以效率為代價:
pattern='some pattern'
for file in ./*; do
grep -- "$pattern" "$file" | while read -r line; do
printf 'file: %s, line: %s\n' "$file" "$line"
done
done
答案2
最近(-ish)版本的 GNU grep 有一個選項-Z
可以使輸出明確,但它主要針對像grep -lZ … | xargs -0
.如果您列出行內容,空字節替換冒號並且行內容仍然以換行符號結束,它仍然有效,但是 shell 不擅長處理空字節,因此您將很難解析此輸出。
一個簡單的解決方案(效能略有下降)是對每個檔案單獨執行 grep。
另一個解決方案是使用 Perl 或 Python 等語言。 Perl 非常擅長模擬 grep; grep REGEX
基本上是perl -ne '/REGEXP/ and print'
。
但如果輸出實際上並不含糊,您可能根本不需要這個。例如,如果匹配行不包含冒號,則檔案名稱是一行中直到最後一個冒號的所有內容。如果匹配的行全部以SUCCESS
or開頭,FAILURE
並且這些單字沒有出現在檔案名稱中,那麼您可以使用它來定位分隔符號等。
1除非用於-z
過濾以 null 結尾的記錄而不是以換行符結尾的記錄,否則 null 既是文件名終止符又是結果終止符;沒有-o
輸出仍然是明確的,交替輸出記錄是檔案名稱和輸出中的匹配記錄。
答案3
如何安全地使用 grep 的輸出在腳本中?
...輸出可以是任何類型資料結構,只要我可以在上面運行程式碼即可。
Shell 腳本實際上沒有資料結構。有數組,但僅此而已 - 將管道輸出安全地輸入數組並不容易。 (檔名能包含換行符。
最好的方法是運行程式碼在 shell 腳本中對檔案進行操作的方法是僅對檔案執行程式碼,而不是嘗試儲存檔案名稱以供以後使用。
為此,請使用find
:
find somedir -type f -exec grep -q somepattern {} \; -exec somecommand {} \;
然而,透過更仔細地閱讀你的問題,看起來你實際上並不想運行程式碼在您的文件中,您只想對某些行進行一些文字處理。在這種情況下,GNU Grep 選項-z
可能就是您想要的。再加上 Sed 或 Awk 的知識,就可以解決您的問題。
更改文件命名約定可能是明智之舉。