Linux 命令:如何“查找”仅文本文件?
- 2024-11-05 08:38:00
- admin 原创
- 55
问题描述:
经过 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
将使其立即匹配文本文件,因此运行速度非常快。如果您担心空格,您可以将 改为-print
a-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 命令:find
、file
和grep
。
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"* ]]
像以前一样使用 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"
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件