셸에서 확장명으로 총 파일 크기 계산


13

우리는 lucene 색인을 포함하는 디렉토리 세트를 가지고 있습니다. 각 인덱스는 서로 다른 파일 형식 (확장자로 구분)의 혼합입니다. 예 :

0/index/_2z6.frq
0/index/_2z6.fnm
..
1/index/_1sq.frq
1/index/_1sq.fnm
..

(약 10 가지 확장 프로그램입니다)

다음과 같은 파일 확장자로 합계를 얻고 싶습니다.

.frq     21234
.fnm     34757
..

나는 du / awk / xargs의 다양한 조합을 시도했지만 정확하게 이것을하는 것이 까다로운 것을 발견했습니다.


이 게시물에 해당 문제에 대한 답변이 있습니다. serverfault.com/questions/183431/…
Blueicefield

각 파일 유형의 총 크기 또는 각 파일 유형의 총 수를 알고 싶습니까?
user9517

총 파일 크기입니다.
barnybug

답변:


19

주어진 확장에 대해 사용

find /path -name '*.frq' -exec ls -l {} \; | awk '{ Total += $5} END { print Total }'

해당 유형의 총 파일 크기를 가져옵니다.

그리고 약간의 생각 후에

#!/bin/bash

ftypes=$(find . -type f | grep -E ".*\.[a-zA-Z0-9]*$" | sed -e 's/.*\(\.[a-zA-Z0-9]*\)$/\1/' | sort | uniq)

for ft in $ftypes
do
    echo -n "$ft "
    find . -name "*${ft}" -exec ls -l {} \; | awk '{total += $5} END {print total}'
done

찾은 각 파일 형식의 크기를 바이트 단위로 출력합니다.


고마워, 어떤 확장으로 요약 된 것을 찾고 있었다 (예를 들어 정렬하는 것이 편리하기 때문에)
barnybug

내 업데이트를 확인하십시오.
user9517

큰 감사합니다. awk는 일부 숫자에 대한 과학적 결과물을 생성하며이를 비활성화 할 수 있습니다. .fdt 3.15152e + 10
barnybug

1
일반 정수를 제공하기 위해 약간 조정되었습니다 : find. -name "* $ {ft}"-print0 | xargs -0 du -c | 총 grep | awk '{print $ 1}'
barnybug

1
사용할 수있는 -iname파일 확장 파일 검색의 경우를 구분을 할 수 있습니다.
Aaron Copley

6

bash는 버전 4와 함께, 당신은 단지 호출 할 필요가 find, ls그리고 awk필요가 없습니다 :

declare -A ary

while IFS=$'\t' read name size; do 
  ext=${name##*.}
  ((ary[$ext] += size))
done < <(find . -type f  -printf "%f\t%s\n")

for key in "${!ary[@]}"; do 
  printf "%s\t%s\n" "$key" "${ary[$key]}"
done

이 스크립트는 탭 문자가있는 파일 이름에서는 제대로 작동하지 않습니다. 변경 read name sizeread size name하고 -printf "%f\t%s\n"하기 -printf "%s\t%f\n"를 해결해야한다.
matt

1
이 스크립트는 확장자가없는 파일에서는 잘 작동하지 않습니다. 전체 파일 이름을 확장명으로 취급합니다. 추가 if [ "$name" == "$ext" ]; then ext="*no_extension*"; fiext=${name##*.}당신이 그것을 방지하기 위해 필요합니다. 이렇게하면 확장자가없는 모든 파일이 *no_extension*그룹으로 저장됩니다 ( 파일 이름에 유효한 문자가 아니기 *no_extension*때문에 사용 *
matt

4

두 번째 열을 나누고 .마지막 부분 (확장자)을 배열로 저장했습니다.

#!/bin/bash

find . -type f -printf "%s\t%f\n" | awk '
{
 split($2, ext, ".")
 e = ext[length(ext)]
 size[e] += $1
}

END{
 for(i in size)
   print size[i], i
}' | sort -n

그런 다음 모든 확장의 총 크기 (바이트)를 얻습니다.

60055 gemspec
321991 txt
2075312 html
2745143 rb
13387264 gem
47196526 jar

1

많은 수의 파일로 작업하기 위해 더 빠른 버전으로 Iain의 스크립트를 확장합니다.

#!/bin/bash

ftypes=$(find . -type f | grep -E ".*\.[a-zA-Z0-9]*$" | sed -e 's/.*\(\.[a-zA-Z0-9]*\)$/\1/' | sort | uniq)

for ft in $ftypes
do
    echo -ne "$ft\t"
    find . -name "*${ft}" -exec du -bcsh '{}' + | tail -1 | sed 's/\stotal//'
done


0

이 두 명령을 사용하여 해결했습니다.

FILES=$(find . -name '*.c')
stat -c %s ${FILES[@]} | awk '{ sum += $1 } END { print ".c" " " sum }'

0

질문에 대한 내 답변 버전 :

#!/bin/bash

date >  get_size.log
# Lists all files
find . -type f -printf "%s\t%f\n" | grep -E ".*\.[a-zA-Z0-9]*$" | sort -h | awk  '
{
        split($2, ext, ".")
        e = ext[length(ext)]
        # Checks that one extension could be found
        if(length(e) < length($2)) {
                # Check that file size are bigger than 0
                if($i > 0) {
                        # Check that extension not are integer
                        if(!(e ~/^[0-9]+$/)) {
                                size[e] += $1
                        }
                }
        }
        if(length(e) == length($2)) {
                size["blandat"] += $1
        }
}

END{
 for(i in size)
   print size[i], i
}' | sort -n >> get_size.log
echo
echo
echo The result are in file get_size.log

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.