您需要将通配符匹配添加到目标目录。
比较 foo.sh 中的两个 for 循环(“原始”被注释掉)。
我还将 grep 命令修改为只是一个回显,所以你有一个
预览将要尝试执行的内容的简便方法。
foo.sh 的示例输出
编辑:我添加了 -r(下面,在 foo.sh 中)来检查 dir $1 的读取权限。那将很难解决;当我针对一个未读目录进行测试时,它看起来就像目录中没有任何东西一样(即使它有一个 *.java 和一个 *.class 文件,如上所示)。
更清楚地说,针对不可读的目录运行看起来像这样(这没有 -r 检查):
$ chmod a-r tmp
$ ./foo.sh tmp
$1="tmp"
processing tmp/* file
grep -o '<myphrase>' "tmp/*" | wc -l
$
请注意上面的“处理 tmp/* 文件”行。
for 循环将文字字符“tmp/*”输入到 $f 变量中。
这很好,如果模式不匹配任何内容,这正是通配符扩展的工作方式。
但我们不会检查 grep 中的错误代码,所以这可能很难
注意 grep 抱怨 "file tmp/* not found"。
foo.sh 输出(修订)
$ chmod a+r tmp
$ ./foo.sh
$1=""
Error: no directory specified.
$ ./foo.sh foo.sh
$1="foo.sh"
Error: "foo.sh" is not a dir.
$ ./foo.sh tmp
$1="tmp"
processing tmp/Foo.class file
grep -o '<myphrase>' "tmp/Foo.class" | wc -l
processing tmp/Foo.java file
grep -o '<myphrase>' "tmp/Foo.java" | wc -l
$ chmod a-r tmp
$ ./foo.sh tmp
$1="tmp"
Error: no read permissions on dir "tmp".
$
foo.sh
#!/bin/bash
echo "\$1=\"$1\""
if [ -z "$1" ]; then
echo "Error: no directory specified."
exit 1
fi
if [ ! -e "$1" ]; then
echo "Error: dir \"$1\" does not exist."
exit 1
fi
if [ ! -d "$1" ]; then
echo "Error: \"$1\" is not a dir."
exit 1
fi
if [ ! -r "$1" ]; then
echo "Error: no read permissions on dir \"$1\"."
exit 1
fi
# maybe default to "." if $1 is empty ?
# original: for f in "$1"
for f in "$1"/*
do
echo "processing $f file"
echo "grep -o '<myphrase>' \"$f\" | wc -l"
# maybe change myphrase to $2 ?
done
此外,正如其他地方所指出的,您正在编写自己的“查找”命令版本。还有一种可能……
那么 find 呢?
我添加这个只是为了鼓励你在 some 点查看 find 命令。
免责声明:编写自己的脚本完全没问题。
研究和了解如何自己动手是很有价值的。
find 确实很复杂,但从长远来看,它值得攀登 find 的学习曲线。
请注意,以下 99% 只是 cmets。
ezfind.sh(一个例子)
#!/bin/bash
# example ussage:
# ezfind.sh "$HOME/my_dir" "foo.*bar"
# "$1" is the start point, any directory path (relative or absolute).
# -type f limits matches to regular files (e.g. probably dont
# want to run grep dirs or devices).
# exec args ar funky, see below.
# Optional: see bottom of this script for notes about -depth
# to limit how deep find will search.
#------------------------------------------------------
find "$1" -type f -exec grep -i -o "$2" '{}' ';'
# \________/ \___/ \__/ \_/
# | | | |
# command ----------------+ | | |
# pattern for grep ----------------+ | |
# find replaces {} w/filename------------+ |
# find exepects a semicolon for end-of-cmd---+
# Quoting is funky for -exec arguments.
# The values have to to survive current bash interpretation,
# so they can be passed to find's argument list.
# Then find turns around and passes them to grep's argument list.
# The semicolon is normally a bash statement separator so we
# need to quote it (or escape it) so it gets passed to find
# as part of the arg list.
# find -exec will replace {} with current filename.
# find gives you a crazy amount of file name, file type and date range options.
# search for all file names in /what/ever matching "*.txt"
# search for all file names matching "*.sh" modified in the last hour.
# for more on find, see here:
# http://www.softpanorama.org/Tools/Find/using_exec_option_and_xargs_in_find.shtml
#
# What if I don't want to search every sub-folder, all the way down?
# Also about not traversing subdirectories, consider the -depth modifer.
# To just search the target directory, modify the above to read:
# find "$1" -maxdepth 0 ....
# To just search the target directory and immediate subdirectories...
# find "$1" -maxdepth 1 ....
# For a nice summary of -depth, see here:
# http://www.tech-recipes.com/rx/31/limit-the-depth-of-search-using-find/