I currently use the following command, but it's a little unwieldy to type. What's a shorter alternative?
我目前使用以下命令,但输入有点笨拙。什么是更短的选择?
find . -name '*.txt' -exec grep 'sometext' '{}' \; -print
Here are my requirements:
这是我的要求:
- limit to a file extension (I use SVN and don't want to be searching through all those .svn directories)
- can default to the current directory, but it's nice to be able to specify a different directory
- must be recursive
限制文件扩展名(我使用SVN,不想搜索所有这些.svn目录)
可以默认为当前目录,但能够指定不同的目录是很好的
必须是递归的
UPDATE: Here's my best solution so far:
更新:到目前为止,这是我最好的解决方案:
grep -r 'sometext' * --include='*.txt'
UPDATE #2: After using grep for a bit, I realized that I like the output of my first method better. So, I followed the suggestions of several responders and simply made a shell script and now I call that with two parameters (extension and text to find).
更新#2:在使用grep之后,我意识到我更喜欢第一种方法的输出。所以,我按照几个响应者的建议,简单地制作了一个shell脚本,现在我用两个参数(扩展名和要查找的文本)调用它。
9 个解决方案
#1
9
grep has -r (recursive) and --include (to search only in files and directories matching a pattern).
grep具有-r(递归)和--include(仅搜索与模式匹配的文件和目录)。
#2
3
If its too unweildy, write a script that does it and put it in your personal bin directory. I have a 'fif' script which searches source files for text, basically just doing a single find like you have here:
如果它太不合适,请编写一个执行此操作的脚本并将其放入您的个人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 "$@"
it started life as a single-line script and got features added over the years as I needed them.
它起源于单行脚本,并且在我需要的时候添加了多年来添加的功能。
#3
3
This is much more efficient since it invokes grep
many fewer times, though it's hard to say it's more succinct:
这样效率要高得多,因为它调用grep的次数要少很多,尽管很难说它更简洁:
find . -name '*.txt' -print0 | xargs -0 grep 'sometext' /dev/null
Notes:
/find -print0
and xargs -0
makes pathnames with embedded blanks work correctly.
/ find -print0和xargs -0使具有嵌入空格的路径名正常工作。
The /dev/null
argument makes sure grep always prepends a filename.
/ dev / null参数确保grep始终包含文件名。
#5
3
I second ephemient's suggestion of ack. I'm writing this post to highlight a particular issue.
我第二次提出了ack的建议。我写这篇文章是为了突出一个特定的问题。
In response to jgormley (in the comments): ack
is available as a single file which will work wherever the right Perl version is installed (which is everywhere).
回应jgormley(在评论中):ack作为单个文件提供,可以在安装了正确的Perl版本的任何地方使用(无处不在)。
Given that on non-Linux platforms grep
regularly does not accept -R
, arguably using ack
is more portable.
鉴于在非Linux平台上,grep经常不接受-R,可以说使用ack更具可移植性。
#6
2
I use zsh, which has recursive globbing. If you needed to look at specific filetypes, the following would be equivalent to your example:
我使用zsh,它有递归的globbing。如果您需要查看特定的文件类型,以下内容将等同于您的示例:
grep 'sometext' **/*.txt
If you don't care about the filetype, the -r option will be better:
如果你不关心文件类型,-r选项会更好:
grep -r 'sometext' *
Although, A minor tweak to your original example will give you exactly what you want:
虽然,对原始示例的一个小调整将为您提供您想要的内容:
find . -name '*.txt' \! -wholename '*/.svn/*' -exec grep 'sometext' '{}' \; -print
If this is something you do frequently, make it a function (put this in your shell config):
如果你经常这样做,那就把它变成一个函数(把它放在你的shell配置中):
function grep_no_svn {
find . -name "${2:-*}" \! -wholename '*/.svn/*' -exec grep "$1" '{}' \; -print
}
Where the first argument to the function is the text you're searching for. So:
函数的第一个参数是您要搜索的文本。所以:
$ grep_here_no_svn "sometext"
Or:
$ grep_here_no_svn "sometext" "*.txt"
#7
1
You could write a script (in bash or whatever -- I have one in Groovy) and place it on the path. E.g.
你可以写一个脚本(用bash或其他什么 - 我在Groovy中有一个)并将它放在路径上。例如。
$ myFind.sh txt targetString
where myFind.sh is:
myFind.sh在哪里:
find . -name "*.$1" -exec grep $2 {} \; -print
#8
0
I usualy avoid the "man find" by using grep $(find . -name "*,txt")
我通常使用grep $(find。-name“*,txt”)来避免“man find”
#9
0
You say that you like the output of your method (using find) better. The only difference I can see between them is that grepping multiple files will put the filename on the front.
你说你更喜欢你的方法的输出(使用find)。我可以在它们之间看到的唯一区别是,grepping多个文件会将文件名放在前面。
You can always (in GNU grep, but you must be using that or -r and --include wouldn't work) turn the filename off by using -h (--no-filename). The opposite, for anyone who does want filenames but has to use find for some other reason, is -H (--with-filename).
你可以随时(在GNU grep中,但你必须使用它或-r并且--include不起作用)通过使用-h( - no-filename)关闭文件名。相反,对于任何想要文件名但由于某些其他原因必须使用find的人来说,是-H( - with-filename)。
#1
9
grep has -r (recursive) and --include (to search only in files and directories matching a pattern).
grep具有-r(递归)和--include(仅搜索与模式匹配的文件和目录)。
#2
3
If its too unweildy, write a script that does it and put it in your personal bin directory. I have a 'fif' script which searches source files for text, basically just doing a single find like you have here:
如果它太不合适,请编写一个执行此操作的脚本并将其放入您的个人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 "$@"
it started life as a single-line script and got features added over the years as I needed them.
它起源于单行脚本,并且在我需要的时候添加了多年来添加的功能。
#3
3
This is much more efficient since it invokes grep
many fewer times, though it's hard to say it's more succinct:
这样效率要高得多,因为它调用grep的次数要少很多,尽管很难说它更简洁:
find . -name '*.txt' -print0 | xargs -0 grep 'sometext' /dev/null
Notes:
/find -print0
and xargs -0
makes pathnames with embedded blanks work correctly.
/ find -print0和xargs -0使具有嵌入空格的路径名正常工作。
The /dev/null
argument makes sure grep always prepends a filename.
/ dev / null参数确保grep始终包含文件名。
#4
#5
3
I second ephemient's suggestion of ack. I'm writing this post to highlight a particular issue.
我第二次提出了ack的建议。我写这篇文章是为了突出一个特定的问题。
In response to jgormley (in the comments): ack
is available as a single file which will work wherever the right Perl version is installed (which is everywhere).
回应jgormley(在评论中):ack作为单个文件提供,可以在安装了正确的Perl版本的任何地方使用(无处不在)。
Given that on non-Linux platforms grep
regularly does not accept -R
, arguably using ack
is more portable.
鉴于在非Linux平台上,grep经常不接受-R,可以说使用ack更具可移植性。
#6
2
I use zsh, which has recursive globbing. If you needed to look at specific filetypes, the following would be equivalent to your example:
我使用zsh,它有递归的globbing。如果您需要查看特定的文件类型,以下内容将等同于您的示例:
grep 'sometext' **/*.txt
If you don't care about the filetype, the -r option will be better:
如果你不关心文件类型,-r选项会更好:
grep -r 'sometext' *
Although, A minor tweak to your original example will give you exactly what you want:
虽然,对原始示例的一个小调整将为您提供您想要的内容:
find . -name '*.txt' \! -wholename '*/.svn/*' -exec grep 'sometext' '{}' \; -print
If this is something you do frequently, make it a function (put this in your shell config):
如果你经常这样做,那就把它变成一个函数(把它放在你的shell配置中):
function grep_no_svn {
find . -name "${2:-*}" \! -wholename '*/.svn/*' -exec grep "$1" '{}' \; -print
}
Where the first argument to the function is the text you're searching for. So:
函数的第一个参数是您要搜索的文本。所以:
$ grep_here_no_svn "sometext"
Or:
$ grep_here_no_svn "sometext" "*.txt"
#7
1
You could write a script (in bash or whatever -- I have one in Groovy) and place it on the path. E.g.
你可以写一个脚本(用bash或其他什么 - 我在Groovy中有一个)并将它放在路径上。例如。
$ myFind.sh txt targetString
where myFind.sh is:
myFind.sh在哪里:
find . -name "*.$1" -exec grep $2 {} \; -print
#8
0
I usualy avoid the "man find" by using grep $(find . -name "*,txt")
我通常使用grep $(find。-name“*,txt”)来避免“man find”
#9
0
You say that you like the output of your method (using find) better. The only difference I can see between them is that grepping multiple files will put the filename on the front.
你说你更喜欢你的方法的输出(使用find)。我可以在它们之间看到的唯一区别是,grepping多个文件会将文件名放在前面。
You can always (in GNU grep, but you must be using that or -r and --include wouldn't work) turn the filename off by using -h (--no-filename). The opposite, for anyone who does want filenames but has to use find for some other reason, is -H (--with-filename).
你可以随时(在GNU grep中,但你必须使用它或-r并且--include不起作用)通过使用-h( - no-filename)关闭文件名。相反,对于任何想要文件名但由于某些其他原因必须使用find的人来说,是-H( - with-filename)。