私の質問を正しい質問に再編集しました。
パスワード:
#!/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個のファイルがあり、リストされた62個のファイルに合計13個の異なる名前があるため、サーバーの数は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
。次に、ハッシュ配列を使用して、最初の(0番目)要素(サーバー名の接頭辞など)が%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ソートの自然なソートオプション - サーバー名に同じ長さのゼロパディング番号がないため必要です)。
または
- 単一行のキーの並べ替え
perl
(ただし、次を使用する必要があります)自然::ソートCPANモジュール)
しかし、このPerlの1行スクリプトは、コマンドラインではなく(または同様に)標準入力からファイル名のリストを取得するように簡単に変更できます。また、先行パス名を削除するために簡単に変更することもできます。これにより、使いやすくなります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