如何在 Git Bash 中處理檔案名稱中的空格

如何在 Git Bash 中處理檔案名稱中的空格

我編寫了以下腳本以在 Windows 7 下的 Git Bash 下運行:

#!/usr/bin/env sh
for logfile in `find -name "*.log" -o -name "*.err" -o -name "*.out"`
do
    echo $logfile
    grep "api/" "$logfile"
done

問題是當檔案名稱中有空格時 grep 會阻塞。我認為雙引號應該解決這個問題,但它不合作。

有想法嗎?

答案1

解決方案1

最接近的解決方案是使用findwith-print0並讀取輸出while read …

find -name "*.log" -o -name "*.err" -o -name "*.out" -type f -print0 | while IFS= read -r -d '' logfile; do
    ...

繼續使用"$logfile"引號,就像使用變數時一樣。

解決方案2

另一個解決方案是find完全不使用,而只grep在多個文件上運行:

shopt -s nullglob
shopt -s globstar
grep "api/" **/*.log **/*.err **/*.out

在這裡,globstar啟用目錄與**.nullglob如果這些檔案副檔名之一不存在,您應該進行設定以防止錯誤。

但這僅適用於有限的文件集,因為您可能會達到命令列參數的最大長度。

為什麼會發生錯誤?

您永遠不應該在( 或,或任何其他輸出帶有空格的檔案名稱的函數)for的輸出上運行。讀findls本文了解有關為什麼這是一個問題以及可以採取哪些措施來解決該問題的更多資訊。

簡而言之,Bash 透過空格分割參數。假設您有三個檔案 、afoo barb那麼該行將計算為:

for logfile in a foo bar b; do

顯然,Bash 會設定logfileafoobarb,這不是您想要的。如果您可以手動指定 的輸入for,則可以將這些檔案名稱括在引號中以解決問題。

為了自動執行此操作,解決方案是用NUL字元分隔這些檔案名稱(這就是該-print0選項的作用),然後再次根據該字元分割輸出NUL(這就是-d ''in 的作用read)。

相關內容