Linux 命令:如何“查找”仅文本文件?

2024-11-05 08:38:00
admin
原创
55
摘要:问题描述:经过 Google 搜索几次后,我得到了以下结果:find my_folder -type f -exec grep -l "needle text" {} ; -exec file {} ; | grep text 这非常不方便,并且会输出不需要的文本,例如 m...

问题描述:

经过 Google 搜索几次后,我得到了以下结果:

find my_folder -type f -exec grep -l "needle text" {} ; -exec file {} ; | grep text

这非常不方便,并且会输出不需要的文本,例如 mime 类型信息。有更好的解决方案吗?我在同一个文件夹中有很多图像和其他二进制文件,还有许多需要搜索的文本文件。


解决方案 1:

我知道这是一个老话题,但我偶然发现了它,并想分享我的方法,我发现这是一种非常快速的方法来查找find非二进制文件:

find . -type f -exec grep -Iq . {} ; -print

grep 的选项-I告诉它立即忽略二进制文件,而.选项与 一起-q将使其立即匹配文本文件,因此运行速度非常快。如果您担心空格,您可以将 改为-printa-print0以便将管道改为xargs -0或类似的东西(感谢@lucas.werkmeister 的提示!)

另外,第一个点仅对某些 BSD 版本(例如 OS X)才是必要的find,但如果您想将其放在别名或类似的东西中,那么一直将它放在那里并没有什么坏处。

编辑:正如@ruslan 正确指出的那样,-and由于它是隐含的,因此可以省略。

解决方案 2:

基于这个问题:

grep -rIl "needle text" my_folder

解决方案 3:

为什么它不方便?如果你需要经常使用它,但又不想每次都输入它,那么只需为其定义一个 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
}

解决方案 4:

find . -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 \n  | xargs -0 file \n  | grep -P text \n  | cut -d: -f1 \n  | xargs -i% grep -Pil "$1" "%"

解决方案 5:

另一种方法:

# find . |xargs file {} ; |grep "ASCII text"

如果您也想要空文件:

#  find . |xargs file {} ; |egrep "ASCII text|empty"

解决方案 6:

这是一个简化版本,其中包含扩展解释,适合像我这样试图学习如何在一行中输入多个命令的初学者。

如果你要分步骤写出这个问题,它看起来会像这样:

// For every file in this directory
// Check the filetype
// If it's an ASCII file, then print out the filename

为了实现这一点,我们可以使用三个 UNIX 命令:findfilegrep

find将检查目录中的每个文件。

file将返回文件类型。在本例中,我们希望返回“ASCII 文本”

grep将在输出中查找关键字“ASCII”file

那么我们如何才能将它们串在一起呢?有多种方法可以做到这一点,但我发现按照伪代码的顺序进行操作最有意义(尤其是对我这样的初学者来说)。

find ./ -exec file {} ";" | grep 'ASCII'

看起来很复杂,但分解一下就不难了:

find ./= 查看此目录中的每个文件。该find命令将打印出与“表达式”匹配的任何文件的文件名,或路径后面的任何内容,在我们的例子中是当前目录或./

最重要的是要理解,第一位之后的所有内容都将被评估为 True 或 False。如果为 True,则将打印出文件名。如果不是,则命令继续。

-exec= 此标志是 find 命令中的一个选项,它允许我们使用其他命令的结果作为搜索表达式。这就像在函数中调用函数一样。

file {}= 在 中调用的命令find。该file命令返回一个字符串,告诉您文件的文件类型。通常,它看起来像这样:file mytextfile.txt。在我们的例子中,我们希望它使用命令正在查看的任何文件find,因此我们放入花括号{}以充当空变量或参数。换句话说,我们只是要求系统为目录中的每个文件输出一个字符串。

";"= 这是必需的find,也是我们命令末尾的标点符号-exec。如果您需要通过运行来获取更多解释,请参阅“find”手册man find

| grep 'ASCII'=|是一个管道。管道获取左侧的输出并将其用作右侧的输入。它获取find命令的输出(一个字符串,是单个文件的文件类型)并测试它是否包含字符串'ASCII'。如果包含,则返回 true。

现在,当命令返回 true 时,右边的表达式find ./也将返回 true grep。瞧!

解决方案 7:

这个怎么样:

$ grep -rl "needle text" my_folder | tr '
' '' | xargs -r -0 file | grep -e ':[^:]*text[^:]*$' | grep -v -e 'executable'

如果您想要不包含文件类型的文件名,只需添加最终sed过滤器。

$ grep -rl "needle text" my_folder | tr '
' '' | xargs -r -0 file | grep -e ':[^:]*text[^:]*$' | grep -v -e 'executable' | sed 's|:[^:]*$||'

-e 'type'您可以通过在最后一个命令中添加更多选项来过滤掉不需要的文件类型grep

编辑:

如果你的xargs版本支持该-d选项,上面的命令会变得更简单:

$ grep -rl "needle text" my_folder | xargs -d '
' -r file | grep -e ':[^:]*text[^:]*$' | grep -v -e 'executable' | sed 's|:[^:]*$||'

解决方案 8:

以下是我的做法...

1.制作一个小脚本来测试一个文件是否是纯文本istext:

#!/bin/bash
[[ "$(file -bi $1)" == *"file"* ]]
  1. 像以前一样使用 find

find . -type f -exec istext {} ; -exec grep -nHi mystring {} ;

解决方案 9:

我对 histumness 的回答有两个疑问:

  • 它仅列出文本文件。它实际上并未按要求搜索它们。要实际搜索,请使用

find . -type f -exec grep -Iq . {} ; -and -print0 | xargs -0 grep "needle text"
  • 它会为每个文件生成一个 grep 进程,这非常慢。更好的解决方案是

find . -type f -print0 | xargs -0 grep -IZl . | xargs -0 grep "needle text"

或者简单地

find . -type f -print0 | xargs -0 grep -I "needle text"

这仅花费 0.2 秒,而上面的解决方案(2.5GB 数据/7700 个文件)则需要 4 秒,即速度快了 20 倍

此外,没有人提到ag、Silver Searcher或ack-grep作为替代方案。如果其中之一可用,它们是更好的替代方案:

ag -t "needle text"    # Much faster than ack
ack -t "needle text"   # or ack-grep

最后要注意的是,要小心误报(将二进制文件当作文本文件)。我已经使用 grep/ag/ack 得到了误报,所以最好先列出匹配的文件,然后再编辑文件。

解决方案 10:

虽然这是一个老问题,但我认为下面的信息会增加这里答案的质量。

当忽略设置了可执行位的文件时,我只需使用此命令:

find . ! -perm -111

为了防止它递归进入其他目录:

find . -maxdepth 1 ! -perm -111

不需要使用管道来混合大量命令,只需使用强大的普通查找命令。

  • 免责声明:它并不完全符合OP 的要求,因为它不检查文件是否为二进制文件。例如,它将过滤掉bash 脚本文件,这些文件本身是文本,但设置了可执行位

话虽如此,我希望这对任何人都有用。

解决方案 11:

我是这样操作的: 1)由于文件太多(~30k)需要搜索,我使用以下命令通过 crontab 每天生成文本文件列表以供使用:

find /to/src/folder -type f -exec file {} ; | grep text | cut -d: -f1 > ~/.src_list &

2)在.bashrc中创建一个函数:

findex() {
    cat ~/.src_list | xargs grep "$*" 2>/dev/null
}

然后我可以使用以下命令进行搜索:

findex "needle text"

嗨呀:)

解决方案 12:

我更喜欢 xargs

find . -type f | xargs grep -I "needle text"

如果你的文件名很奇怪,请使用 -0 选项查找:

find . -type f -print0 | xargs -0 grep -I "needle text"

解决方案 13:

  • bash 示例在 /etc 中的所有文本/ascii 文件中搜索文本“eth0”

grep eth0 $(find /etc/-type f -exec file {} \; | egrep -i“text|ascii”| cut -d':'-f1)

解决方案 14:

如果您有兴趣使用file出色的实用程序结合的强大功能通过其魔法字节来查找任何文件类型find,那么这可能会派上用场:

$ # Let's make some test files
$ mkdir ASCII-finder
$ cd ASCII-finder
$ dd if=/dev/urandom of=binary.file bs=1M count=1
1+0 records in
1+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.009023 s, 116 MB/s
$ file binary.file
binary.file: data
$ echo 123 > text.txt
$ # Let the magic begin
$ find -type f -print0 | \n    xargs -0 -I @@ bash -c 'file "$@" | grep ASCII &>/dev/null && echo "file is ASCII: $@"' -- @@

输出:

file is ASCII: ./text.txt

图例:$是我们输入命令的交互式 shell 提示符

您可以修改之后的部分&&以调用其他脚本或执行其他内联操作,例如,如果该文件包含给定的字符串,则对整个文件进行 cat 或在其中查找辅助字符串。

解释:

  • find文件项目

  • xargs每一项作为一行输入到一个bash
    命令/脚本中

  • file通过魔法字节检查文件类型,grep检查 ASCII 是否存在,如果存在,则&&执行下一个命令。

  • find分开打印结果null,这有利于转义带有空格和元字符的文件名。

  • xargs,使用-0选项,将它们null分开读取,-I @@
    获取每条记录并将其用作位置参数/参数传递给 bash 脚本。

  • --forbash确保其后的内容为参数,即使它以-like开头-c,否则可能会被解释为 bash 选项

如果需要查找 ASCII 以外的类型,只需替换grep ASCII为其他类型,例如grep "PDF document, version 1.4"

解决方案 15:

find . -type f | xargs file | grep "ASCII text" | awk -F: '{print $1}'

使用find命令列出所有文件,使用file命令验证它们是文本(不是tar,key),最后使用awk命令过滤并打印结果。

解决方案 16:

grep --recursive --binary-files=without-match --files-with-matches --no-messages . | xargs -d '
' realpath

到目前为止工作令人满意——我正在将grep结果传输到realpath以接收绝对路径。`xargs -d '
'`处理文件名和路径中的潜在空格。

必要时请替换.为所需的搜索路径。

解决方案 17:

这个怎么样

 find . -type f|xargs grep "needle text"
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   681  
  在项目管理领域,集成产品开发(IPD)流程以其高效、协同的特点,被众多企业视为提升产品竞争力的关键。IPD流程强调跨部门、跨职能的紧密合作,以确保产品从概念到市场各个环节的无缝衔接。然而,实现这一目标并非易事,它需要企业深刻理解并掌握IPD流程中的跨部门协作艺术。本文将深入探讨IPD流程中跨部门协作的三个关键点,旨在为...
IPD项目管理咨询   9  
  掌握IPD流程图:提升团队协作的关键路径在当今快速变化的商业环境中,团队协作的效率与效果直接关系到项目的成功与否。集成产品开发(Integrated Product Development,简称IPD)作为一种先进的研发管理理念,通过跨部门、跨领域的协同工作,能够显著提升产品开发的速度与质量。而IPD流程图,则是这一理...
IPD流程阶段   9  
  IPD流程概述:理解其核心价值与实施背景集成产品开发(Integrated Product Development,简称IPD)是一种先进的产品开发管理理念,它强调跨部门协作、市场导向和快速响应变化的能力。IPD流程不仅关注产品本身的技术创新,更注重将市场、研发、生产、销售等各个环节紧密集成,以实现产品从概念到市场的高...
华为IPD是什么   7  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程以其跨部门协作、高效决策和快速响应市场变化的特点,被众多企业视为提升竞争力的关键。然而,实践IPD流程并非易事,项目管理中的种种错误往往阻碍了其效果的充分发挥。本文旨在深入探讨如何在实施IPD流程时避免这些常见错误,...
IPD框架   7  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用