Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux命令:如何';查找';只有文本文件?_Linux_Search_Find - Fatal编程技术网

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"
    
    或者干脆

    find . -type f -print0 | xargs -0 grep -I "needle text"
    
    与上述解决方案(2.5GB数据/7700文件)的4s相比,这只需要0.2s,即快20倍

此外,没有人引用或¸作为替代方案。如果其中之一可用,则它们是更好的选择:

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}'