Linux

如何在 grep 搜尋結果中轉義空格?(文件名)

  • July 18, 2020

當我執行這個:

for f in $(grep -r --include=*.directory "search-string"); do echo $f; done;

我將搜尋結果按搜尋結果文件名中的空格分開。

如何轉義 grep 搜尋結果中的空格?

如果您想要數組中的文件列表並使用 bash shell(4.4 或更高版本),您可以:

readarray -td '' files < <(
 grep -rlZ --include='*.directory' "search-string" .
)

使用zsh外殼:

files=(${(0)"$(grep -rlZ --include='*.directory' "search-string" .)"})

並循環它們:

for file in "${files[@]}"; do
 printf '%s\n' "$file"
done

使用zsh,您可以使用以下命令跳過中間數組:

for file in ${(0)"$(grep -rlZ --include='*.directory' "search-string" .)"}; do
 printf '%s\n' "$file"
}

請注意,不加引號的單詞擴展(如$f$(...))在 中具有非常特殊的含義bash,通常不是您想要的,並且文件名可以包含除 之外的任何字節值0,因此0aka NUL 是唯一可以在表達時安全使用的分隔符文件路徑列表作為帶有分隔符的字節流。這就是GNU的-Z/選項的用途。--null``grep

使用簡單的 shell,例如dash,您可以使用gawkGNU 的輸出grep來生成一個由 shell 引用的文件名列表,sh以評估為 shell 程式碼:

eval set -- "$(
 grep -rlZ --include='*.directory' "search-string" . |
   gawk -v RS='\0' -v ORS=' ' -v q="'" '
     {gsub(q, q "\\" q q); print q $0 q}'
)"

for file do
 printf '%s\n' "$file"
done

如果您可以保證您的文件名不包含換行符,則可以將其簡化為:

IFS='
'
set -o noglob

for file in $(grep -rl --include='*.directory' "search-string" .); do
 printf '%s\n' "$file"
done

set -o noglob如果可以保證文件名也不包含*, ?, [(可能\還有更多 glob 運算符,具體取決於 shell 和 shell 版本),則可以跳過。

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