遍历作为参数传递给 Bash 脚本的文件夹
Iterating through a folder that's passed in as a paramter to a Bash script
我正在尝试遍历一个文件夹,运行 对每个文件进行 grep,然后将它们放入单独的文件中,并用 .res
扩展名进行标记。这是我目前所拥有的....
#!/bin/bash
directory=$(pwd)
searchterms="searchterms.txt"
extension=".end"
usage() {
echo "usage: fmat [[[-f file ] [-d directory ] [-e ext]] | [-h]]"
echo " file - text file containing a return-delimited list of materials"
echo " directory - directory to process"
echo " ext - file extension of files to process"
echo ""
}
while [ "" != "" ]; do
case in
-d | --directory ) shift
directory=
;;
-f | --file ) shift
searchterms=
;;
-e | --extension ) shift
extension=
;;
-h | --help ) usage
exit
;;
* ) usage
exit 1
esac
shift
done
if [ ! -d "$directory" ]; then
echo "Sorry, the directory '$directory' does not exist"
exit 1
fi
if [ ! -f "$searchterms" ]; then
echo "Sorry, the searchterms file '$searchterms' does not exist"
exit 1
fi
echo "Searching '$directory' ..."
for file in "${directory}/*"; do
printf "File: %s\n" ${file}
[ -e "$file" ] || continue
printf "%s\n" ${file}
if [ ${file: -3} == ${extension} ]; then
printf "%s will be processed\n" ${file}
#
# lots of processing here
#
fi
done
我知道这是因为我对 globbing 的理解很差...但是我无法对扩展进行测试。
基本上,我希望能够指定一个源目录、一个包含搜索项的文件和一个要搜索的扩展名。
现在,我意识到可能有更快的方法来做到这一点,例如
grep -f searchterms.txt *.end > allchanges.end.res
但我可能需要对文件进行其他处理,我想将它们保存到单独的文件中:因此 bing.end、bong.end 将被 grep 到 bing.end.res, bong.end.res .
请告诉我,我有多蠢 ;-)
为了完整起见,这是最后一部分,工作,感谢@chepner 和@Gordon Davisson:
echo "Searching '$directory' ..."
for file in "${directory}"/*; do
[ -e "$file" ] || continue
# show which files will be processed
if [[ $file = *.${extension#.} ]]; then
printf "Processing %s \n" "$file"
head -n 1 "${file}" > "${file}.res"
grep -f $searchterms "${file}" >> "${file}.res"
fi
done
您只需要将 *
排除在引号之外,这样它就不会被视为文字 *
:
for file in "${directory}"/*; do
与大多数语言不同,引号不定义字符串(因为 bash
中的所有内容都已经是字符串:它是唯一的数据类型)。他们只是转义引号内的每个字符。 "foo"
与 \f\o\o
完全相同,后者(因为转义大多数字符实际上没有任何效果)与 foo
相同。无论是否引用,所有未被 word-splitting 个字符分隔的字符都是同一单词的一部分。
http://shellcheck.net 会捕捉到这一点,尽管不是最有用的错误消息。 (它还会捕获您没有引用但应该引用的其他参数扩展。)
我正在尝试遍历一个文件夹,运行 对每个文件进行 grep,然后将它们放入单独的文件中,并用 .res
扩展名进行标记。这是我目前所拥有的....
#!/bin/bash
directory=$(pwd)
searchterms="searchterms.txt"
extension=".end"
usage() {
echo "usage: fmat [[[-f file ] [-d directory ] [-e ext]] | [-h]]"
echo " file - text file containing a return-delimited list of materials"
echo " directory - directory to process"
echo " ext - file extension of files to process"
echo ""
}
while [ "" != "" ]; do
case in
-d | --directory ) shift
directory=
;;
-f | --file ) shift
searchterms=
;;
-e | --extension ) shift
extension=
;;
-h | --help ) usage
exit
;;
* ) usage
exit 1
esac
shift
done
if [ ! -d "$directory" ]; then
echo "Sorry, the directory '$directory' does not exist"
exit 1
fi
if [ ! -f "$searchterms" ]; then
echo "Sorry, the searchterms file '$searchterms' does not exist"
exit 1
fi
echo "Searching '$directory' ..."
for file in "${directory}/*"; do
printf "File: %s\n" ${file}
[ -e "$file" ] || continue
printf "%s\n" ${file}
if [ ${file: -3} == ${extension} ]; then
printf "%s will be processed\n" ${file}
#
# lots of processing here
#
fi
done
我知道这是因为我对 globbing 的理解很差...但是我无法对扩展进行测试。
基本上,我希望能够指定一个源目录、一个包含搜索项的文件和一个要搜索的扩展名。
现在,我意识到可能有更快的方法来做到这一点,例如
grep -f searchterms.txt *.end > allchanges.end.res
但我可能需要对文件进行其他处理,我想将它们保存到单独的文件中:因此 bing.end、bong.end 将被 grep 到 bing.end.res, bong.end.res .
请告诉我,我有多蠢 ;-)
为了完整起见,这是最后一部分,工作,感谢@chepner 和@Gordon Davisson:
echo "Searching '$directory' ..."
for file in "${directory}"/*; do
[ -e "$file" ] || continue
# show which files will be processed
if [[ $file = *.${extension#.} ]]; then
printf "Processing %s \n" "$file"
head -n 1 "${file}" > "${file}.res"
grep -f $searchterms "${file}" >> "${file}.res"
fi
done
您只需要将 *
排除在引号之外,这样它就不会被视为文字 *
:
for file in "${directory}"/*; do
与大多数语言不同,引号不定义字符串(因为 bash
中的所有内容都已经是字符串:它是唯一的数据类型)。他们只是转义引号内的每个字符。 "foo"
与 \f\o\o
完全相同,后者(因为转义大多数字符实际上没有任何效果)与 foo
相同。无论是否引用,所有未被 word-splitting 个字符分隔的字符都是同一单词的一部分。
http://shellcheck.net 会捕捉到这一点,尽管不是最有用的错误消息。 (它还会捕获您没有引用但应该引用的其他参数扩展。)