经过从谷歌上的一些搜索,我得到的答案是:
find my_folder -type f -exec grep -l "needle text" {} \; -exec file {} \; | grep text
这种方法非常不方便,输出了一些不必要的文本信息,例如 mime 类型信息。有更好的解决方案吗?我在同一个文件夹中有很多图片和其他二进制文件以及许多需要进行搜索的文本文件。
我知道这是一个旧帖子,但我偶然发现它并想分享我的方法,我发现这是使用 find
查找非二进制文件的一种非常快速的方法:
find . -type f -exec grep -Iq . {} \; -print
-I
选项告诉grep立即忽略二进制文件,.
选项以及-q
将使它立即匹配文本文件,从而使它非常快。如果您担心空格(感谢@lucas.werkmeister的提示!),可以将-print
更改为-print0
以进行管道传输到xargs -0
或其他内容。find
(例如在OS X上),但如果您想将其放入别名或其他东西中,则始终将其放在那里不会有什么影响。
编辑:正如@ruslan正确指出的那样,-and
可以省略,因为它已经被隐含了。为什么这样不方便?如果你需要经常使用它,而且不想每次都输入,只需要定义一个bash函数:
function findTextInAsciiFiles {
# usage: findTextInAsciiFiles DIRECTORY NEEDLE_TEXT
find "$1" -type f -exec grep -l "$2" {} \; -exec file {} \; | grep text
}
将其放入您的.bashrc
中,然后只需运行:
findTextInAsciiFiles your_folder "needle text"
无论何时想要都可以。
编辑以反映OP的编辑:
如果你想剪掉mime信息,你可以添加一个进一步的步骤到管道中来过滤掉mime信息。这应该能够起到作用,只需取出:
之前的内容即可:cut -d':' -f1
:
function findTextInAsciiFiles {
# usage: findTextInAsciiFiles DIRECTORY NEEDLE_TEXT
find "$1" -type f -exec grep -l "$2" {} \; -exec file {} \; | grep text | cut -d ':' -f1
}
file
手册中可以看到:“用户依赖于知道目录中所有可读文件都打印了单词'text'。” - peoro/proc/meminfo
、/proc/cpuinfo
等是文本文件,但是file /proc/meminfo
显示/proc/meminfo: empty
。我想知道是否应该除了检测“text”之外还要测试“empty”,但不确定是否还有其他类型也会报告为空。 - Timo Kähkönencut
以仅获取OP感兴趣的数据。我不明白你的观点... - peorofind . -type f -print0 | xargs -0 file | grep -P text | cut -d: -f1 | xargs grep -Pil "search"
很遗憾,这不是空间节省的。将其放入bash脚本中会使它变得更容易一些。
这是空间安全的:
#!/bin/bash
#if [ ! "$1" ] ; then
echo "Usage: $0 <search>";
exit
fi
find . -type f -print0 \
| xargs -0 file \
| grep -P text \
| cut -d: -f1 \
| xargs -i% grep -Pil "$1" "%"
text.bin
会怎样?2. 如果文件名包含 :
字符会怎样? - thkala# find . |xargs file {} \; |grep "ASCII text"
# find . |xargs file {} \; |egrep "ASCII text|empty"
It only list text files. It does not actually search them as requested. To actually search, use
find . -type f -exec grep -Iq . {} \; -and -print0 | xargs -0 grep "needle text"
It spawns a grep process for every file, which is very slow. A better solution is then
find . -type f -print0 | xargs -0 grep -IZl . | xargs -0 grep "needle text"
or simply
find . -type f -print0 | xargs -0 grep -I "needle text"
This only takes 0.2s compared to 4s for solution above (2.5GB data / 7700 files), i.e. 20x faster.
ag -t "needle text" # Much faster than ack
ack -t "needle text" # or ack-grep
ack
/ag
的人来说,因为他们确实需要跳过在.gitignore
中列出的所有无用文件,只需使用ugrep --ignore-files
(默认使用.gitignore
,但也可以传递其他文件以忽略文件的通配符列表)。当然,要忽略二进制文件,只需使用--ignore-binary
(或-I
)选项。为了提高速度,您可以使用ugrep-indexer
,这是一个伴侣工具,它将预先索引目录中的文件以加快性能。 - undefined#!/bin/bash
[[ "$(file -bi $1)" == *"file"* ]]
2. 如之前一样使用find函数。
find . -type f -exec istext {} \; -exec grep -nHi mystring {} \;
== *"text"* ]]
? - user unknown=~"text"]]
代替。 - user unknown$ grep -rl "needle text" my_folder | tr '\n' '\0' | xargs -r -0 file | grep -e ':[^:]*text[^:]*$' | grep -v -e 'executable'
sed
过滤器即可。$ grep -rl "needle text" my_folder | tr '\n' '\0' | xargs -r -0 file | grep -e ':[^:]*text[^:]*$' | grep -v -e 'executable' | sed 's|:[^:]*$||'
grep
命令中添加更多的-e 'type'
选项来过滤掉不需要的文件类型。xargs
版本支持-d
选项,则上述命令变得更加简单:$ grep -rl "needle text" my_folder | xargs -d '\n' -r file | grep -e ':[^:]*text[^:]*$' | grep -v -e 'executable' | sed 's|:[^:]*$||'
以下是一份简化版的说明,为像我这样的初学者提供了更多的解释,帮助他们学习如何在一行中输入多个命令。
如果你要按步骤写出这个问题,它会像这样:
// For every file in this directory
// Check the filetype
// If it's an ASCII file, then print out the filename
find
、 file
和grep
。
find
会检查目录中的每个文件。
file
会给出文件类型。在我们的例子中,我们要寻找“ASCII文本”的返回结果。
grep
将在来自file
的输出中查找关键字“ASCII”。find ./ -exec file {} ";" | grep 'ASCII'
看起来很复杂,但是当我们把它分解开来时并不难理解:
find ./
= 查看此目录中的每个文件。 find
命令打印与“表达式”或路径之后的任何内容匹配的文件名,在我们的例子中是当前目录或./
。-exec
= 这个标志是find
命令中的一个选项,它允许我们使用其他命令的结果作为搜索表达式。这就像在函数内部调用函数。
file {}
= 在find
内部调用的命令。file
命令返回字符串,告诉您文件的文件类型。通常会像这样:file mytextfile.txt
。在我们的例子中,我们希望它使用find
命令正在查看的任何文件,因此我们将大括号{}
放入其中,充当空变量或参数。换句话说,我们只是要求系统输出目录中每个文件的字符串。
";"
= 这是find
命令所必需的,并且是我们-exec
命令的结尾标点符号。如果需要更多解释,请参阅“find”手册,运行man find
。
| grep 'ASCII'
= |
是一个管道。管道获取左侧的输出,并将其用作右侧的输入。它采用find
命令的输出(一个字符串,是单个文件的文件类型),并测试它是否包含字符串'ASCII'
。如果是,则返回True。find ./
右侧的表达式将在grep
命令返回True时返回True。完成。find . ! -perm -111
find . -maxdepth 1 ! -perm -111
find . -type f -exec grep -Il "" {} \;
。 - Alec Jacobsonfind -type f -exec grep -Iq . {} \; -and -print
,它的优点是保留了find
中的文件;你可以将-print
替换为另一个只对文本文件运行的-exec
。如果让grep
打印文件名,则无法区分包含换行符的文件名。 - Lucas Werkmeisterfind . -type f -exec grep -Il . {} +
要快得多。缺点是无法像 @lucas.werkmeister 建议的那样通过另一个“-exec”进行扩展。 - Henning