如何在grep搜索结果中转义空格?(文件名)

mYn*_*EAm 0 linux shell grep search

当我运行这个:

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

我得到了由搜索结果文件名中的空格分割的搜索结果。

如何转义 grep 搜索结果中的空格?

Sté*_*las 7

如果您想要数组中的文件列表并使用 bash shell(版本 4.4 或更高版本),您可以执行以下操作:

readarray -td '' files < <(
  grep -rlZ --include='*.directory' "search-string" .
)
Run Code Online (Sandbox Code Playgroud)

随着zsh壳:

files=(${(0)"$(grep -rlZ --include='*.directory' "search-string" .)"})
Run Code Online (Sandbox Code Playgroud)

并循环它们:

for file in "${files[@]}"; do
  printf '%s\n' "$file"
done
Run Code Online (Sandbox Code Playgroud)

使用zsh,您可以跳过中间数组:

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

请注意,不加引号的单词扩展(如$f$(...))在 中具有非常特殊的含义bash,通常不是您想要的,并且文件名可以包含除 之外的任何字节值0,因此0又名 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
Run Code Online (Sandbox Code Playgroud)

如果您可以保证您的文件名不包含换行符,您可以将其简化为:

IFS='
'
set -o noglob

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

set -o noglob如果您可以保证文件名也不包含*, ?, [(可能\还有更多的 glob 运算符,取决于 shell 和 shell 版本),您可以跳过。