我是 Linux 新手,我有一个作业需要编写一个 shell 脚本,该脚本打印目录中文件和子目录的所有名称(作为参数给出),并且还应该打印每个文件具有相同名称的文件数从这个目录。
我的问题是,我能够打印所有文件和目录的名称,并且还可以执行任务的第二部分,但我无法将它们放在一起,这意味着我的输出有两个不同的部分:
/some/path
a1
a2
a3
a1 1
a2 1
#a1, a2 files and a3 directory
它应该看起来像这样:
a1 1
a2 1
a3
这是我用来编写 shell 脚本的代码:
#the first part that prints all the names from the directory
mydir=$1
cd $mydir
ls -l $mydir | awk '{print $9}'
#the second part that prints the number of files with the same name for every file
file=$(find $mydir -type f -printf '%f\n' | sort | uniq -c)
echo $file
答案1
在“学习 Linux/shell 脚本”作业的背景下,我会提出以下建议:
mydir=$1
for f in "$mydir"/*
do
printf "%s %d\n" "$f" $(find "$mydir" -name "$f" -print 2>/dev/null | wc -l)
done
对脚本的调整:
- 无需
cd
进入目录ls
即可 - 不需要
awk
文件名;你可以这样ls
,但是... - 单独运行
ls ... awk
意味着find
你得到了单独的输出 find
如果您所做的只是计算输出,则无需专门打印输出- 如果您所做的只是计算输出,则无需对输出进行排序
uniq
如果您想捕获所有内容,则无需使用- 我冒昧地删除了
-type f
以防万一您的作业希望您找到目录同名 - 添加仅
-name "$f"
匹配find
具有匹配名称的文件 - 用于
printf
将文件名和计数组合到同一输出行中 - 无需解析输出
ls
即可获取文件名;这就是for f in "$mydir"/*
——特别是*
——所做的;它扩展以匹配文件名。
我还引用了您的所有变量用法,以防用户提供诸如"this file"
.
这不会在输出中显示隐藏文件;您也可以添加扩展以匹配点文件(隐藏文件)shopt -s dotglob
。"$mydir"/*
作为一个高级警告,如果用户传递包含换行符的文件名来查找,这将错误地计算其中包含换行符的文件名。