Tính tổng kích thước tệp theo phần mở rộng trong shell


13

Chúng tôi có một bộ các thư mục chứa các chỉ mục lucene. Mỗi chỉ mục là một hỗn hợp các loại tệp khác nhau (được phân biệt bởi phần mở rộng), vd:

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

(đó là khoảng 10 phần mở rộng khác nhau)

Chúng tôi muốn có được tổng số phần mở rộng của tệp, ví dụ:

.frq     21234
.fnm     34757
..

Tôi đã thử các kết hợp khác nhau của du / awk / xargs nhưng thấy thật khó để thực hiện chính xác điều này.


Bạn có câu trả lời cho vấn đề đó trong bài đăng này: serverfault.com/questions/183431/
Khăn

Bạn có muốn biết tổng kích thước của từng loại tệp hoặc tổng số lượng của từng loại tệp không?
dùng9517

Tổng kích thước tập tin xin vui lòng.
Barnyorms

Câu trả lời:


19

Đối với bất kỳ tiện ích mở rộng nào bạn sử dụng

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

để có được tổng kích thước tập tin cho loại đó.

Và sau khi suy nghĩ

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

Sẽ xuất kích thước theo byte của từng loại tệp được tìm thấy.


Cảm ơn, đã tìm kiếm thứ gì đó được tóm tắt bởi bất kỳ tiện ích mở rộng nào (vì nó sẽ hữu ích để sắp xếp chẳng hạn)
barnyorms

Kiểm tra cập nhật của tôi.
dùng9517

cảm ơn rất nhiều. awk tạo ra kết quả khoa học cho một số con số, điều này có thể bị vô hiệu hóa: .fdt 3.15152e + 10
barnyorms

1
điều chỉnh một chút để chỉ đưa ra số nguyên đơn giản: find. -name "* $ {ft}" -print0 | xargs -0 du -c | tổng số grep | awk '{print $ 1}'
barnyorms

1
Có thể muốn sử dụng -inameđể làm cho trường hợp tìm kiếm mở rộng tập tin không nhạy cảm.
Aaron Copley

6

Với bash version4, bạn chỉ cần gọi find, lsawkkhông cần thiết:

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

Kịch bản này không hoạt động tốt với tên tệp có ký tự tab. Thay đổi read name sizeđể read size name-printf "%f\t%s\n"để -printf "%s\t%f\n"nên sửa chữa nó.
matt

1
Cũng lưu ý rằng tập lệnh này không hoạt động tốt với các tệp không có phần mở rộng. Nó sẽ coi toàn bộ tên tập tin là phần mở rộng. Thêm if [ "$name" == "$ext" ]; then ext="*no_extension*"; fisau ext=${name##*.}nếu bạn cần ngăn chặn nó. Điều này sẽ đặt tất cả các tệp không có phần mở rộng vào *no_extension*nhóm (Tôi đang sử dụng *no_extension**không phải là ký tự hợp lệ trong tên tệp)
matt

4

Mỗi cột thứ hai được phân tách bởi .và phần cuối (phần mở rộng) được lưu trong mảng.

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

sau đó bạn có mọi kích thước tổng số phần mở rộng tính bằng byte.

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

1

Mở rộng tập lệnh của Iain với phiên bản nhanh hơn để làm việc với số lượng lớn tệp.

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

Tôi đã giải quyết bằng hai lệnh này:

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

0

phiên bản trả lời của tôi cho câu hỏi:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.