在一组文件中查找文本的更简洁方法是什么?

时间:2008-10-21 18:02:20

标签: bash unix shell

我目前使用以下命令,但输入有点笨拙。什么是较短的选择?

find . -name '*.txt' -exec grep 'sometext' '{}' \; -print

以下是我的要求:

  • 限制文件扩展名(我使用SVN,不想搜索所有这些.svn目录)
  • 可以默认为当前目录,但能够指定不同的目录
  • 很高兴
  • 必须递归

更新:到目前为止,这是我最好的解决方案:

grep -r 'sometext' * --include='*.txt'

UPDATE#2:在使用grep之后,我意识到我更喜欢第一种方法的输出。所以,我按照几个响应者的建议,简单地制作了一个shell脚本,现在我用两个参数调用它(扩展名和要查找的文本)。

9 个答案:

答案 0 :(得分:9)

grep具有-r(递归)和--include(仅搜索与模式匹配的文件和目录)。

答案 1 :(得分:3)

如果它太不合适,请编写一个执行此操作的脚本并将其放入您的个人bin目录中。我有一个'fif'脚本搜索源文件中的文本,基本上就像你在这里做一个查找:

#!/bin/bash

set -f  # disable pathname expansion

pattern="-iname *.[chsyl] -o -iname *.[ch]pp -o -iname *.hh -o -iname *.cc
-o -iname *.java -o -iname *.inl"
prune=""
moreargs=true
while $moreargs && [ $# -gt 0 ]; do
    case $1 in
    -h)
        pattern="-iname *.h -o -iname *.hpp -o -iname *.hh"
        shift
        ;;
    -prune)
        prune="-name $2 -prune -false -o $prune"
        shift
        shift
        ;;
    *)
        moreargs=false;
        ;;
    esac
done

find . $prune $pattern | sed 's/ /\\ /g' | xargs grep "$@"

它以单行脚本开始,并且在我需要的时候添加了多年来添加的功能。

答案 2 :(得分:3)

这更有效率,因为它调用grep的次数少了很多次,但很难说它更简洁:

find . -name '*.txt' -print0 | xargs -0 grep 'sometext' /dev/null

注意:

/ find -print0xargs -0使嵌入空格的路径名正常工作。

/dev/null参数确保grep始终包含文件名。

答案 3 :(得分:3)

安装ack并使用

ack -aG'\.txt$' 'sometext'

答案 4 :(得分:3)

我第二次提出了ack的建议。我正在写这篇文章,以突出一个特定的问题。

回应jgormley(在评论中):ack作为单个文件提供,无论安装了正确的Perl版本(无处不在),它都可以使用。

鉴于在非Linux平台grep经常不接受-R,可以说使用ack 更多可移植。

答案 5 :(得分:2)

我使用zsh,它具有递归的globbing。如果您需要查看特定的文件类型,以下内容将等同于您的示例:

grep 'sometext' **/*.txt

如果您不关心文件类型,则-r选项会更好:

grep -r 'sometext' *

尽管如此,对原始示例的一个小调整将为您提供您想要的内容:

find . -name '*.txt' \! -wholename '*/.svn/*' -exec grep 'sometext' '{}' \; -print

如果您经常这样做,请将其设为函数(将其放入shell配置中):

function grep_no_svn {
    find . -name "${2:-*}" \! -wholename '*/.svn/*' -exec grep "$1" '{}' \; -print
}

函数的第一个参数是您要搜索的文本。所以:

$ grep_here_no_svn "sometext"

或者:

$ grep_here_no_svn "sometext" "*.txt"

答案 6 :(得分:1)

你可以写一个脚本(用bash或其他什么 - 我在Groovy中有一个)并将它放在路径上。 E.g。

$ myFind.sh txt targetString

myFind.sh在哪里:

find . -name "*.$1" -exec grep $2 {} \; -print

答案 7 :(得分:0)

我通常使用grep $(find . -name "*,txt")

来避免“找人”

答案 8 :(得分:0)

你说你更喜欢你的方法的输出(使用find)。我可以在它们之间看到的唯一区别是,grepping多个文件会将文件名放在前面。

你总是可以(在GNU grep中,但你必须使用它或-r并且--include不起作用)使用-h( - no-filename)关闭文件名。相反,对于任何想要文件名但由于某些其他原因必须使用find的人来说,是-H( - with-filename)。