我知道我的以下任务可以使用更简单的“查找”注释来完成,但我正在尝试使用递归调用来实现解决方案。我正在查看特定目录并尝试获取所有子目录中任何文件名的最大长度。但是,我的递归仅向下一级工作,因此它基本上返回特定目录或其子目录中最长的文件名。
#! /bin/bash
export maxlen=0
findmaxr()
{
if [ $# -eq 0 ] ; then
echo "Please pass arguments. Usage: findmax dir"
exit -1
fi
if [ ! -d "$1" ]; then
echo "No such directory exist."
exit -2
fi
for file in $(/bin/ls $1)
do
if [ -d "$file" ] ; then
findmaxr $file # Recursively call the method for subdirectories
else
cur=${#file}
if [ $maxlen -lt $cur ] ; then
maxlen=$cur
fi
fi
done
echo "The file with the longest name has [$maxlen] characters."
}
findmaxr `pwd`
答案1
尝试:
#! /bin/bash
export maxlen=0
findmaxr()
{
if [ $# -eq 0 ] ; then
echo "Please pass arguments. Usage: findmax dir"
exit 1
fi
if [ ! -d "$1" ]; then
echo "No such directory exist."
exit 2
fi
for file in "$1"/*
do
if [ -d "$file" ] ; then
findmaxr "$file" # Recursively call the method for subdirectories
else
f=${file##*/}
cur=${#f}
if [ $maxlen -lt $cur ] ; then
maxlen=$cur
fi
fi
done
}
findmaxr "$PWD"
echo "The file with the longest name has [$maxlen] characters."
讨论
不要这样做:
for file in $(/bin/ls $1)
即使文件名不包含空格,解析ls
仍然不可靠。
相比之下,这将可靠地工作:
for file in "$1"/*
此外,此表单将保留父目录的名称,这是您需要下降到子目录的名称。例如,使用下面示例中的目录结构,输出ls
仅显示该目录的裸文件名d 1
:
$ ls 'd 1'
12345 d 2
相比之下, 的输出'd 1'/*
在输出中包含父目录的名称:
$ echo 'd 1'/*
d 1/12345 d 1/d 2
通过保留父目录名称,我们可以使递归工作。
由于file
现在包含完整路径,因此我们需要在确定其长度之前删除目录名称。这是通过删除前缀来完成的:
f=${file##*/}
例子
考虑这个文件结构:
$ find .
.
./d 1
./d 1/12345
./d 1/d 2
./d 1/d 2/1234567
./d 1/d 2/d 3
./d 1/d 2/d 3/123456789
./script
现在,让我们运行我们的脚本:
$ bash script
The file with the longest name has [9] characters.