我必须编写一个脚本,该脚本以目录名作为参数,并将该目录中所有文件名的最大长度写入标准输出。如果函数的参数不是目录名,则写入错误消息。
我怎样才能做到这一点
答案1
脚本而不是函数。这将打印最长文件名中的字符数,这就是我理解你想要的:
#!/bin/bash
# include hidden files
shopt -s dotglob
# if the first argument is a directory
if [ -d "$1" ]; then
# move to that directory
cd "$1"
# set a variable to 0
long=0
# loop over all the files
for i in *; do
# print the filename - remove this line after testing
echo "$i"
# if the length of the current filename is longer
# than the value of the variable long, assign the
# length of the current filename to long
(( (${#i} > $long) )) && long=${#i}
done
# print the value of long
echo $long
# if the first argument wasn't a directory, print an error
else
printf "%s\n" "Not a directory"
fi
这将利用dotglob
设置,使 globbing*
包含隐藏文件。要查看其效果,请在主目录中运行以下命令:
ls -d *
shopt -s dotglob
ls -d *
要关闭shopt
设置,-u
例如使用shopt -u dotglob
。
我们需要检查参数是否是一个目录,因此我们使用对目录进行测试的if
命令test
(以其形式) :[
-d
if [ -d "$1" ]; then
这意味着,如果传递给脚本的第一个参数是存在的目录的名称,则执行以下操作。$1
是第一个参数,我们将其用双引号引起来,以阻止 shell 对变量的值进行进一步扩展。
我们需要进入目录,因为我们需要获取文件名的长度,而不是整个路径(绝对路径或相对路径)。我们不想这样:
$ for i in ~/*; do [ -d "$i" ] && echo "$i"; done
/home/zanna/custom
/home/zanna/Desktop
/home/zanna/Documents
/home/zanna/Downloads
...
因为如果我们计算长度,$i
我们将得到完整路径的长度。我们可以做一些文本处理技巧(也许还有一些我不知道的更聪明的技巧)来摆脱路径,但解析文件名通常是不可靠的,如果我们更改目录,我们可以轻松地让 shell 为我们计算字符数,以便${#var}
给出长度var
(我相信这算数人物而不是字节)。请注意,脚本在子 shell 中运行,而不是在当前 shell 中运行,因此如果脚本更改目录,调用该脚本的 shell 的工作目录不会受到影响。
我的脚本用于for
循环遍历目录中的文件。执行该操作的行是
(( (${#i} > $long) )) && long=${#i}
这意味着,如果 的当前值的长度i
大于 的当前值,则将的long
长度赋给。由于我们首先将其设置为 0,因此第一个文件名将始终长于(因为它尽可能短)。此后,只有较长文件名的长度才能替换 的值。由于我们知道和只包含整数,因此我们不需要用双引号保护它们。在 Bash 中创建一个算术上下文,以便我们可以使用其数学含义(感谢i
long
long
long
long
${#i}
long
((
>
穆鲁感谢你在其他地方向我指出了这一点)。