我可以列出文件夹中的所有文本文件(按 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
;\x
GNU 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/
则删除该部分并仅打印文件名,否则不打印任何内容。