암호:

암호:

내 질문을 올바른 질문으로 다시 편집했습니다.

암호:

#!/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 한 줄 스크립트는 명령줄 대신(또는 마찬가지로) 표준 입력에서 파일 이름 목록을 가져오도록 쉽게 수정할 수 있습니다. 또한 선행 경로 이름을 제거하기 위해 쉽게 수정할 수도 있습니다. 이렇게 하면 사용하기가 더 쉬워집니다 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

관련 정보