如何仅在文本文件中搜索字符串? (递归地)

如何仅在文本文件中搜索字符串? (递归地)

我可以列出文件夹中的所有文本文件(按 mimetype):

find . -type f -print0 | xargs -0 file -i | fgrep -i text | sed 's/:$//g' 2>/dev/null | awk 'BEGIN {FS=": "} {print $1}'

好的。但是我如何添加“fgrep”,以在这些文件中搜索“STRING”(不需要正则表达式,这就是 fgrep 的原因)。

这不好:

fgrep -iR "STRING" *

因为它开始搜索 ISO 文件、二进制文件......

Fedora14/bash。

答案1

第一的grep:您可以告诉它不要搜索二进制文件 - 使用开关-I- 正如手册页所述:

-I     Process a binary  file  as  if  it  did  not  contain  matching data;
       this  is  equivalent  to  the --binary-files=without-match option.

第二, the find: 为了避免使用 xargs 和大量管道,请使用程序-exec测试find。您可以使用以下方法轻松创建一系列逻辑测试:每个连续的-exec执行每个连续的测试如果之前的所有命令都返回 0(成功完成)。

答案2

@rozcietrzewiacz 的解决方案是一个很好的解决方案,但如果您仍然想保留文本文件(由 返回的file),您可以仔细构建文件名数组,然后grep在该数组上执行命令。

我想有以下几点:

  • 没有文件名时有换行符(但可以存在空格);
  • file支持-0和选项的实用程序-i
  • \xGNU sed,或支持十进制字符代码的sed 。

这是一个例子

#!/bin/bash

get_file_list() {
  local path="$1"
  find "$path" -type f -exec file -0i {} + |
    sed -n '/\x00  *text\//s/\x00.*//p'
}

list=()
while IFS= read -r line; do
  list+=("$line")
done < <(get_file_list .)

# to choose options and pattern
grep -i pattern "${list[@]}"

sed命令采用来自 的一系列文本行file,由文件名、NUL 字节和 mime 类型组成。如果在第二部分(NUL 之后)中有单词,text/则删除该部分并仅打印文件名,否则不打印任何内容。

相关内容