我正在编写一个程序打印指定目录的文件和目录。但我必须忽略某些类型的文件。我们将它们存储在.ignorefile
.
因此,为了获取我想要的文件,我使用 find 函数。但是,我每次都会遇到同样的错误:No such file or directory
。
而且,当我在终端上尝试时,它可以使用相同的参数完美地工作。
一个例子 :
在我的忽略文件中,我有:
*.txt, *.cpp
当我执行
.sh
文件时,我输入两个参数:忽略文件和目录。然后,当我扫描文件中的所有文本以构造参数文件时,我调用我的
store()
函数。
在这里你可以看到我的代码:
function store(){
dir="$1"
find_arg="$2" # Dir ! -name '*.txt' ! -name '*.cpp' -print
echo $find_arg
cmd=`find "$find_arg"`
echo $cmd
}
这里是构建 find_args 的函数:
function backup()
{
if [ $1="-i" ] && [ -f $2 ]
then
backignore=$2
if [ $3="-d" ] && [ -d $4 ]
then
directory=$4
find_arg=" $directory"
while IFS='' read -r line || [[ -n "$line" ]]; do
find_arg+=" ! -name "
find_arg+="'"
find_arg+=$line
find_arg+="'"
done < "$backignore"
find_arg+=" -print"
store $directory "$find_arg"
else
echo "please entrer a right directory"
fi
else
echo "Please enter a right ignore file"
fi
}
backup $1 $2 $3 $4
我称之为“sh”文件
./file.sh -i ignorefile -d Source
输出:
Source ! -name '\*.cpp' ! -name '\*.txt' -print
Source/unix_backup/example_files/backignore
Source/unix_backup/example_files/Documents/rep1/file3.txt
Source/unix_backup/example_files/Documents/rep1/file4.cpp
Source/unix_backup/example_files/Documents/rep3
Source/unix_backup/example_files/Documents/rep3/rep4
Source/unix_backup/example_files/Documents/rep3/rep4/file7.txt
Source/unix_backup/example_files/Documents/rep3/rep4/file8.cpp
答案1
答案2
您说您的 .ignorefile 有,
*.txt, *.cpp
但从显示的输出来看,它看起来像有\*.txt, \*.cpp
。转义*
是问题的根源,它告诉find
排除带有文字星号的文件,而不是将其用作全局通配符。所以,不要这样做。此版本的脚本修复了一些缺陷并稍微简化了它。除此之外,它将 arg 处理(并使用 sh 内置的 getopts)与
backup()
函数的主逻辑分开。
function store() {
echo find "$@"
find "$@"
}
function backup() {
directory="$1"
backignore="$2"
# skip comments and blank lines
sed -e 's/#.*// ; /^[[:space:]]*$/d' "$backignore" |
while IFS= read -r line ; do
find_arg+=" ! -name '$line'"
done
find_arg+=" -print"
store "$directory" $find_arg
}
usage() {
echo "$(basename $0) [ -d directory ] [ -i ignorefile ]"
exit 1
}
directory=''
backignore='.ignorefile' # default
while getopts "i:d:h" opt ; do
case "$opt" in
d) directory="$OPTARG" ;;
i) backignore="$OPTARG" ;;
*) usage ;;
esac
done
[ -z "$directory" ] && echo "Please provide a directory." && usage
backup "$directory" "$backignore"