![암호:](https://linux55.com/image/126928/%EC%95%94%ED%98%B8%3A.png)
내 질문을 올바른 질문으로 다시 편집했습니다.
암호:
#!/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 한 줄 스크립트는 명령줄 대신(또는 마찬가지로) 표준 입력에서 파일 이름 목록을 가져오도록 쉽게 수정할 수 있습니다. 또한 선행 경로 이름을 제거하기 위해 쉽게 수정할 수도 있습니다. 이렇게 하면 사용하기가 더 쉬워집니다 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