我试图遍历目录中的所有文件,其名称作为命令行参数(例如myfolder)给出。对于每个文件,grep命令应该在文件夹上运行,并计算在文本文件中找到短语(例如myphrase)的次数。
当我运行我的代码时,类似于下面,我得到错误"没有这样的文件或目录"。我尝试使用./myscript.sh myfolder
和./myscript.sh /[fullpath]/myfolder
调用脚本,但它们都会导致相同的错误。
for f in "$1"
do
echo "processing $f file"
grep -o '<myphrase>' "$f" | wc -l
done
关于出了什么问题的任何想法? 如果它有助于从与文本文件相同的文件夹中运行脚本,并且必须使用文件夹名称作为参数调用该命令 - 我必须遵循这两个烦人的要求。
编辑:为此文件夹运行ls -ld会显示drwxr-xr-x@ 829 user staff 28186 7 Feb 17:19 my folder
答案 0 :(得分:2)
如上所述anubhava:
在你的for循环使用中:
for f in "$1"/*
do
...
done
然后,您可以检查f是否是包含以下内容的文件:
[[ -f $f ]]
在循环中执行必要的逻辑:
[[ -f $f ]] && grep -o '<myphrase>' "$f" | wc -l
总结如下:
for f in "$1"/*
do
echo "processing $f file"
[[ -f $f ]] && grep -o '<myphrase>' "$f" | wc -l
done
答案 1 :(得分:0)
您需要为目标目录添加通配符匹配。
比较foo.sh中的两个for循环(“原始”被注释掉)。
此外,我将grep命令修改为只是一个回声,所以你有一个
简单的方法来预览将要尝试执行的内容。
编辑:我添加了-r(下面,在foo.sh中)来检查dir $ 1的读取权限。这很难成功;当我针对一个无读取目录进行测试时,它只是看起来像目录中没有任何内容(即使它有* .java和* .class文件,如上所示)。
更清楚的是,针对不可读的dir运行看起来像这样(这是没有-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抱怨“文件tmp / *未找到”。
$ 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".
$
#!/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”命令版本。另一种可能性是......
我添加这个只是为了鼓励你在某些点查看find命令。
免责声明:编写自己的脚本完全正常。 研究和理解如何推销你自己是有价值的。
发现确实很复杂,但从长远来看,非常值得攀登发现的学习曲线。
请注意,以下99%只是评论。
#!/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/
答案 2 :(得分:0)
从目录详细信息中,似乎目录名称中有一个空格:
drwxr-xr-x @ 829用户工作人员28186 7月17日17:19我的文件夹
尝试运行如下脚本或从目录名称中删除空格:)
./ myscript.sh"我的文件夹&#34;
答案 3 :(得分:-1)
你可以这样做:
find <directory> -type f -exec egrep -c '<regular expression>' {} +
请注意,由于find
找不到不存在的文件,因此无需检查文件是否存在。另请注意,find
遍历找到的子目录(-maxdepth 1
的可调行为)。
E.g:
find /usr/include -type f -exec egrep -c 'int128' {} +