パスワード:

パスワード:

私の質問を正しい質問に再編集しました。

パスワード:

#!/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

配列変数を使用するのが正しい解決策であるようです。

  1. 複数の「...」費用がかかる実行を避けてください。
  2. ループ内のすべてのファイル数を計算します。
  3. 最後に結果を印刷します。
  4. コードはサーバーの数に関係なく同じように動作します。

パスワード

#!/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

関連情報