Linux命令:如何';查找';只有文本文件?
在谷歌搜索了几次之后,我想到的是:Linux命令:如何';查找';只有文本文件?,linux,search,find,Linux,Search,Find,在谷歌搜索了几次之后,我想到的是: find my_folder -type f -exec grep -l "needle text" {} \; -exec file {} \; | grep text 这非常不方便,并输出不需要的文本,如mime类型信息。有更好的解决办法吗?我在同一个文件夹中有很多图像和其他二进制文件,还有很多需要搜索的文本文件。这个怎么样 find . -type f|xargs grep "needle text" 为什么不舒服?如果您需要经常使用它,并且不想每
find my_folder -type f -exec grep -l "needle text" {} \; -exec file {} \; | grep text
这非常不方便,并输出不需要的文本,如mime类型信息。有更好的解决办法吗?我在同一个文件夹中有很多图像和其他二进制文件,还有很多需要搜索的文本文件。这个怎么样
find . -type f|xargs grep "needle text"
为什么不舒服?如果您需要经常使用它,并且不想每次都键入它,请为它定义一个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
}
这个怎么样:
$ 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|:[^:]*$||'
不幸的是,这并不能节省空间。将其放到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" "%"
#/bin/bash
#如果[!“$1”];然后
echo“用法:$0”;
出口
fi
找到-类型f-print0\
|xargs-0文件\
|grep-P文本\
|切割-d:-f1\
|xargs-i%grep-Pil“$1”“%”
以下是我是如何做到的
一,。制作一个小脚本来测试文件是否为纯文本
istext:
二,。像以前一样使用find
find . -type f -exec istext {} \; -exec grep -nHi mystring {} \;
基于:
grep-rIl“needle text”我的文件夹
我知道这是一条旧线索,但我无意中发现了它,并想与大家分享我的方法,我发现这是一种非常快速的方法,可以使用查找
只查找非二进制文件:
find . -type f -exec grep -Iq . {} \; -print
grep的-I
选项告诉它立即忽略二进制文件,
选项和-q
将使它立即匹配文本文件,因此运行速度非常快。您可以将-print
更改为-print0
,以便将管道连接到xargs-0
或其他与空间有关的内容(感谢您的提示,@lucas.werkmeister!)
此外,第一个点仅对某些BSD版本的find
是必需的,例如在OS X上,但如果您想将其放在别名或其他内容中,则始终将其放在那里不会有任何影响
编辑:正如@ruslan正确指出的那样,-和
可以省略,因为它是隐含的。我这样做:
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"
HTH:)我更喜欢xargs
find . -type f | xargs grep -I "needle text"
如果文件名很奇怪,请使用-0选项进行查找:
find . -type f -print0 | xargs -0 grep -I "needle text"
我对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"
与上述解决方案(2.5GB数据/7700文件)的4s相比,这只需要0.2s,即快20倍find . -type f -print0 | xargs -0 grep -I "needle text"
ag-t“针形文本”#比ack快得多
ack-t“针文本”或ack grep
最后,请注意,注意误报(二进制文件作为文本文件)。我已经在使用grep/ag/ack时出现了假阳性,所以最好在编辑文件之前先列出匹配的文件。- bash示例在所有text/ascii文件中的/etc中插入文本“eth0”
grep eth0$(find/etc/-typef-exec file{}\| egrep-i“text | ascii”| cut-d':'-f1)这是一个简化版本,对像我这样的初学者进行了扩展解释,他们试图学习如何在一行中放置多个命令 如果您要分步骤写出问题,它将如下所示:
// 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”
那么我们如何把这些串成一行呢?有多种方法可以做到这一点,但我发现按照伪代码的顺序来做是最有意义的(特别是对于像我这样的初学者)
find./-exec文件{}”;“| grep'ASCII'
看起来很复杂,但当我们将其分解时还不错:
find./
=查看此目录中的每个文件。find
命令打印出与“expression”匹配的任何文件的文件名,或路径后面的任何文件的文件名,在本例中是当前目录或/
要理解的最重要的事情是,在第一位之后的所有内容都将被评估为True或False。如果为True,将打印出文件名。如果不是,则命令继续
-exec
=此标志是find命令中的一个选项,允许我们使用其他命令的结果作为搜索表达式。这就像在函数中调用函数
file{}
=在find
中调用的命令。file
命令返回一个字符串,告诉您文件的文件类型。通常,它看起来是这样的:文件mytextfile.txt
。在我们的例子中,w
find . -type f -print0 | xargs -0 grep -I "needle text"
// For every file in this directory
// Check the filetype
// If it's an ASCII file, then print out the filename
find . ! -perm -111
find . -maxdepth 1 ! -perm -111
# find . |xargs file {} \; |grep "ASCII text"
# find . |xargs file {} \; |egrep "ASCII text|empty"
$ # 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 | \
xargs -0 -I @@ bash -c 'file "$@" | grep ASCII &>/dev/null && echo "file is ASCII: $@"' -- @@
file is ASCII: ./text.txt
find . -type f | xargs file | grep "ASCII text" | awk -F: '{print $1}'