我再次将我的问题编辑为正确的问题。
代码:
#!/bin/bash
unset file_count
for i in *@cfg2html*.html; do
hostname=${i%%@*}
echo $hostname
done
file_count=`ls -dq **cfg2html@*.html* | wc -l`
echo $file_count
for i in $hostname; do
if [ "$hostname[i]" != "$hostname[i++]" ];
then $((server_count++));
echo $server_count;
fi
done
代码结束
我能够从文件中提取主机名,但我希望能够计算不同主机名的数量。主机名数量的计数被分配给 $server_count 变量。例如,总共有 62 个文件,但服务器数量为 13 个,因为列出的 62 个文件总共有 13 个不同的名称,我希望能够通过修复我的代码来计算服务器数量(13)。如何根据比较文件名以正确的方式修改我的代码以获得服务器计数(在本例中为 13)。服务器名称为:ebr-t3、ebr-t4、ebr-t、j-laemgcd.bank-banque-canada.ca 等。13 个不同的服务器名称但位于 62 个文件中。
到目前为止的输出指示文件和文件数量:
ebr-t3
ebr-t3
ebr-t3
ebr-t3
ebr-t3
ebr-t3
ebr-t4
ebr-t4
ebr-t
ebr-t
ebr-t
ebr-t
ebr-t
ebr-t
ebr-t
j-laemgcd.bank-banque-canada.ca
j-laemgcd.bank-banque-canada.ca
j-laemgcd.bank-banque-canada.ca
j-laemgcd.bank-banque-canada.ca
j-laemgcd.bank-banque-canada.ca
j-laemgcd.bank-banque-canada.ca
j-laemgcd.bank-banque-canada.ca
j-laemgcd.bank-banque-canada.ca
j-laemgcd.bank-banque-canada.ca
j-laengine2.bank-banque-canada.ca
j-laengine2.bank-banque-canada.ca
j-laengine2.bank-banque-canada.ca
j-laengine2.bank-banque-canada.ca
j-laengine2.bank-banque-canada.ca
j-lafinrepos2.bank-banque-canada.ca
j-lafinrepos2.bank-banque-canada.ca
j-lafinrepos2.bank-banque-canada.ca
j-lafinrepos2.bank-banque-canada.ca
j-lafinrepos2.bank-banque-canada.ca
j-laimdir1.bank-banque-canada.ca
j-laimdir1.bank-banque-canada.ca
j-laimdir1.bank-banque-canada.ca
j-laimdir1.bank-banque-canada.ca
j-laimdir1.bank-banque-canada.ca
j-laimdir1.bank-banque-canada.ca
j-laimdir1.bank-banque-canada.ca
j-laimdir1.bank-banque-canada.ca
j-laimdir1.bank-banque-canada.ca
j-laimdir1.bank-banque-canada.ca
j-laimdir2.bank-banque-canada.ca
j-laimdir2.bank-banque-canada.ca
j-laimdir2.bank-banque-canada.ca
j-laimdir2.bank-banque-canada.ca
j-laimdir2.bank-banque-canada.ca
ucdmfmddv11
ucdmfmddv11
ucdmfmddv11
ucdmfmddv21
uldmfindv11
uldmfindv11
uldmfindv21
uldmfindv21
uldmsatdv11
uodbfindv11
uodbsatdv11
uodbsatdv11
uodbsatdv11
[root@ebr-t ENV7]#
[root@ebr-t ENV7]# file_count=`ls -dq **cfg2html@*.html* | wc -l`
[root@ebr-t ENV7]# echo $file_count
62
答案1
使用数组变量似乎是正确的解决方案:
- 避免多次“...”昂贵的执行。
- 在一个循环中对所有文件进行计数。
- 最后打印结果。
- 对于任意数量的服务器,该代码的工作方式都是相同的。
代码
#!/bin/bash
unset file_count_ITS_ENV7_t
for i in ebr-t*@*.html; do
n=${i%%@*} # remove everything after @
n=${n##ebr-t} # remove leading ebr-t
: $(( file_count_ITS_ENV7_t[n]++)) # increment count of files for server n
done
file_count_ITS_ENV7_total=0
server_count_ITS_ENV7_total=0
for i in "${!file_count_ITS_ENV7_t[@]}"; do
if [[ ${file_count_ITS_ENV7_t[i]} -ge 1 ]]; then
echo "Server number $i has ${file_count_ITS_ENV7_t[i]} files"
: $((file_count_ITS_ENV7_total+=${file_count_ITS_ENV7_t[i]}))
: $((server_count_ITS_ENV7_total++))
fi
done
echo "total number of files $file_count_ITS_ENV7_total"
echo "total number of servers $server_count_ITS_ENV7_total"
答案2
perl -e 'foreach (@ARGV) { my @F=split(/@/,$_); $servers{$F[0]}++ };
END { printf "%s: %i\n", $_, $servers{$_} for (keys %servers) }' *@*
此 perl 脚本将命令行上给出的每个文件名按@
字符拆分到数组中@F
。然后,它使用散列数组%servers
来记录每次看到第一个(第零个)元素@F
(即服务器名称前缀)的计数。
当它处理完命令行上列出的所有文件名后,它会打印每个前缀的摘要 ( server: count
)。
具有问题中给出的示例文件名的目录中的示例输出:
$ perl -e 'foreach (@ARGV) { my @F=split(/\@/,$_); $servers{$F[0]}++ };
END { printf "%s: %i\n", $_, $servers{$_} for (keys %servers)}' *@*
ebr-t: 2
ebr-t2: 1
ebr-t3: 2
ebr-t4: 1
请注意,散列数组(又称关联数组)是无序的,因此输出顺序实际上是随机的(它恰好在这次特定运行中以正确的顺序出现)。如果您希望对它们进行排序,您可以:
- 将输出通过管道传输到
sort -V
(GNU sort 的自然排序选项 - 需要,因为您的服务器名称没有用零填充的数字达到相同的长度)
或者
- 对单行中的键进行排序
perl
(但您需要使用自然::排序CPAN模块)
顺便说一句,这个 perl 单行脚本可以很容易地修改为从标准输入而不是(或以及)命令行获取文件名列表。并且还可以轻松修改以删除任何前导路径名。这将使其易于使用,例如find
.
答案3
问题已经完全改变了。这几乎就像一个新问题。
根据问题中发布的列表,有 15 个服务器(不是 13 个):
ebr-t
ebr-t3
ebr-t4
j-laemgcd.bank-banque-canada.ca
j-laengine2.bank-banque-canada.ca
j-lafinrepos2.bank-banque-canada.ca
j-laimdir1.bank-banque-canada.ca
j-laimdir2.bank-banque-canada.ca
ucdmfmddv11
ucdmfmddv21
uldmfindv11
uldmfindv21
uldmsatdv11
uodbfindv11
uodbsatdv11
获取所有详细信息的代码:
file_count=0
server_count=0
shopt -s nullglob
unset server_name s_count
declare -a server_name s_count
s=""
i=-1
for f in *@cfg2html@*@*@.html; do
file_count=$((file_count+1))
s1=${f%%@*}
if [[ $s != $s1 ]]; then
i=$((i+1))
s=$s1
server_name[i]=$s
server_count=$((server_count+1))
fi
s_count[i]=$((${s_count[i]}+1))
#echo "[$s] ${f%%@*} <${server_count[i]}>"
done
echo "file_count=$file_count"
echo "server_count=$server_count"
declare -p server_name
declare -p s_count
执行时(将脚本放置在服务器文件所在的位置):
$ cd dir_of_files
$ ./script
file_count=62
server_count=15
declare -a server_name=([0]="ebr-t3" [1]="ebr-t4" [2]="ebr-t" [3]="j-laemgcd.bank-banque-canada.ca" [4]="j-laengine2.bank-banque-canada.ca" [5]="j-lafinrepos2.bank-banque-canada.ca" [6]="j-laimdir1.bank-banque-canada.ca" [7]="j-laimdir2.bank-banque-canada.ca" [8]="ucdmfmddv11" [9]="ucdmfmddv21" [10]="uldmfindv11" [11]="uldmfindv21" [12]="uldmsatdv11" [13]="uodbfindv11" [14]="uodbsatdv11")
declare -a s_count=([0]="6" [1]="2" [2]="7" [3]="9" [4]="5" [5]="5" [6]="10" [7]="5" [8]="3" [9]="1" [10]="2" [11]="2" [12]="1" [13]="1" [14]="3")
如果目录为空,执行时您将得到:
$ ./script
file_count=0
server_count=0
declare -a server_name
declare -a s_count