如何在 shell 脚本中创建一个计数器,每次当前目录中的文件超过 8 行时该计数器都会增加,之后如何生成两个列表,其中一个包含超过 8 行的文件,另一个列表包含超过 8 行的文件。其他少于 8 行的文件?我尝试过这个,但我确信这是不正确的。
contor=0
while [ contor -le 100 ]
do
echo $contor
contor=expr $contor + 1
done
答案1
#!/bin/bash
shopt -s nullglob dotglob
long_files=()
short_files=()
for name in ./*; do
[[ ! -f $name ]] && continue
numlines=$( wc -l <"$name" )
if [[ numlines -gt 8 ]]; then
long_files+=( "$name" )
elif [[ numlines -lt 8 ]]; then
short_files+=( "$name" )
fi
done
printf 'There are %d files with more than 8 lines:\n' "${#long_files[@]}"
printf '\t%s\n' "${long_files[@]}"
printf 'There are %d files with less than 8 lines:\n' "${#short_files[@]}"
printf '\t%s\n' "${short_files[@]}"
这实际上会按照您的要求进行操作,方法是迭代当前目录中的所有名称并将名称分为两个列表(数组)long_files
和short_files
,具体取决于文件的行数是多于还是少于八行。恰好有八行的文件不存储在列表中。-f
测试和语句会跳过与非常规文件(即目录等)相对应的名称continue
。
行数是使用 计算的wc -l
,因此无需使用计数器来计算文件中的各个行。
该脚本设置nullglob
和dotglob
shell 选项,使我们能够正确处理完全空的目录和隐藏文件。
最后输出两个列表。
测试运行:
$ bash script.sh
There are 1 files with more than 8 lines:
./script.sh
There are 3 files with less than 8 lines:
./.bash_profile
./.bashrc
./.zshrc
要创建两个包含列表的文件,请将列表打印到上述脚本末尾的文件中
printf '%s\n' "${long_files[@]}" >long_files.list
printf '%s\n' "${short_files[@]}" >short_files.list
或打印到程序主循环中的文件,而不是将名称添加到数组中:
#!/bin/bash
shopt -s nullglob dotglob
rm -f long_files.list short_files.list
for name in ./*; do
[[ ! -f $name ]] && continue
numlines=$( wc -l <"$name" )
if [[ numlines -gt 8 ]]; then
printf '%s\n' "$name" >>long_files.list
elif [[ numlines -lt 8 ]]; then
printf '%s\n' "$name" >>short_files.list
fi
done
到数数长度超过八行的文件数,使用在检测到长文件时递增的计数器变量,或者如果使用长文件和短文件的数组,则获取"${#long_files[@]}"
循环后的长文件数(如我在第一段代码)。