it-swarm-tr.com

Bir bash betiğindeki bir dosyanın boyutunu nasıl alabilirim?

Bir bash betiğindeki bir dosyanın boyutunu nasıl alabilirim?

Daha sonra kullanabilmek için bunu bir bash değişkenine nasıl atayabilirim?

271
haunted85

GNU sistemindeyse en iyi bahsiniz:

stat --printf="%s" file.any

erkek stat :

bayt cinsinden% s toplam boyut

Bir bash betiğinde:

#!/bin/bash
FILENAME=/home/heiko/dummy/packages.txt
FILESIZE=$(stat -c%s "$FILENAME")
echo "Size of $FILENAME = $FILESIZE bytes."

NOT: Mac OS X'te terminalde stat kullanma hakkında bilgi için @ chbrown'ın cevabı konusuna bakın.

262
b01
file_size_kb=`du -k "$filename" | cut -f1`

stat kullanmayla ilgili sorun, bunun bir GNU (Linux) uzantısı olmasıdır. du -k ve cut -f1 POSIX tarafından belirtilir ve bu nedenle herhangi bir Unix sistemine taşınabilir.

Solaris, örneğin, bash ile birlikte gelir ancak stat ile birlikte gönderilmez. Yani bu tamamen varsayımsal değil.

ls, çıktının tam biçiminin belirtilmemesi bakımından benzer bir soruna sahiptir, bu nedenle çıktısının ayrıştırılması taşınabilir olarak yapılamaz. du -h ayrıca bir GNU uzantısıdır.

Mümkün olan yerlerde taşınabilir yapılara sadık kalın ve gelecekte birisinin hayatını kolaylaştıracaksınız. Belki kendi.

97
Nemo

"Kelime sayısı" komutunu da kullanabilirsiniz (wc):

wc -c "$filename" | awk '{print $1}'

wc ile ilgili sorun dosya adını ekleyecek ve çıktıyı girintileyecektir. Örneğin:

$ wc -c somefile.txt
    1160 somefile.txt

Yalnızca bir dosya boyutu sayısı elde etmek için tam olarak yorumlanan bir dili veya akış düzenleyicisini zincirlemekten kaçınmak istiyorsanız, wc'in dosya adını asla görmemesi için girdiyi dosyadan yeniden yönlendirmeniz yeterlidir:

wc -c < "$filename"

Bu son form, aşağıdaki Gilles ile belirtildiği gibi bir Shell değişkeni olarak aradığınız değeri kolayca yakalamak için komut ikamesi ile kullanılabilir.

size="$(wc -c <"$filename")"
79
Eugéne

BSD'ler (macOS'lar) stat farklı bir biçim bağımsız değişken bayrağı ve farklı alan belirleyicilerine sahiptir. man stat(1) öğesinden:

  • -f format: Belirtilen biçimi kullanarak bilgileri görüntüler. Geçerli biçimlerin açıklaması için FORMATLAR bölümüne bakın.
  • ... FORMATLAR bölümü ...
  • z: Dosyanın bayt cinsinden boyutu.

Şimdi hep birlikte:

stat -f%z myfile1.txt

NOT: GNU/Linux sistemlerinde stat komutunun nasıl kullanılacağı hakkında @ b01'in cevabı konusuna bakın. :)

53
chbrown

Ne demek istediğinize büyüklüğüne göre değişir.

size=$(wc -c < "$file")

dosyadan okunabilecek bayt sayısını verecektir. IOW, dosyanın içeriğinin boyutudur. Ancak dosyanın içeriğini okuyacaktır (dosya bir optimizasyon olarak çoğu wc uygulamasında normal bir dosya veya normal dosyaya sembolik bağlantı dışında). Bunun yan etkileri olabilir. Örneğin, adlandırılmış bir kanal için okunanlar artık tekrar okunamaz ve sonsuz büyüklükteki /dev/zero Veya /dev/random Gibi şeyler için biraz zaman alacaktır. Bu aynı zamanda dosya için read iznine ihtiyacınız olduğu ve dosyanın son erişim zaman damgasının güncellenebileceği anlamına gelir.

Bu standart ve taşınabilirdir, ancak bazı wc uygulamalarının bu çıktıda önde gelen boşluklar içerebileceğini unutmayın. Onlardan kurtulmanın bir yolu kullanmaktır:

size=$(($(wc -c < "$file")))

veya dash çıktı üretmediğinde (dosya açılamadığında olduğu gibi) yash veya wc içindeki boş bir aritmetik ifadeyle ilgili bir hatayı önlemek için:

size=$(($(wc -c < "$file") +0))

ksh93, wc builtin'e (etkinleştirmeniz koşuluyla, command /opt/ast/bin/wc Olarak da çağırabilirsiniz), bu da onu Shell'deki normal dosyalar için en verimli hale getirir.

Çeşitli sistemlerde stat adlı bir komut vardır; bu, stat() veya lstat() sistem çağrılarına arabirimdir.

Bu, inode'da bulunan bilgileri bildirir. Bu bilgilerden biri st_size Özelliğidir. Normal dosyalar için, içeriğin boyutu budur (hata olmadığında ondan ne kadar veri okunabilir (çoğu wc -c Uygulamanın optimizasyonlarında kullandığı yöntem budur). Simgeler için hedef yolun bayt cinsinden boyutu budur. Adlandırılmış kanallar için, sisteme bağlı olarak, 0 veya şu anda boru arabelleğindeki bayt sayısıdır. Sisteme bağlı olarak, temel depolama alanının bayt cinsinden 0 veya boyutuna sahip olduğunuz blok cihazları için aynıdır.

Bu bilgileri almak için dosyanın okuma iznine ihtiyacınız yoktur, sadece bağlı olduğu dizinde arama iznine sahip olursunuz.

Kronolojik sıraya göre:

  • IRIX stat (90'lar):

    stat -qLs -- "$file"
    

    st_size [lstat()) $file özniteliğini döndürür veya:

    stat -s -- "$file"
    

    $file bir sembolik bağlantı olduğu zaman aynıdır; bu durumda, sembolik bağlantı çözünürlüğünden sonra dosyanın st_size dosyasıdır.

  • zshstat builtin (şimdi zstat olarak da bilinir) zsh/stat modülünde (zmodload zsh/stat) (1997):

    stat -L +size -- $file # st_size of file
    stat +size -- $file    # after symlink resolution
    

    veya bir değişkende saklamak için:

    stat -L -A size +size -- $file
    

    açıkçası, bu Shell'deki en etkili olan bu.

  • GNU stat (2001); 2005'ten beri BusyBox stat da (kopyalanan GNU stat):

    stat -c %s -- "$file"  # st_size of file
    stat -Lc %s -- "$file" # after symlink resolution
    

    (-L öğesinin anlamının IRIX veya zshstat ile ters çevrildiğini unutmayın.

  • BSD'ler stat (2002):

    stat -f %z -- "$file"  # st_size of file
    stat -Lf %z -- "$file" # after symlink resolution
    

Veya Perl gibi bazı kodlama dillerinin stat()/lstat() işlevini kullanabilirsiniz:

Perl -le 'print((lstat shift)[7])' -- "$file"

AIX ayrıca, tüm stat() (lstat() değil, bu yüzden sembolik bağlantılarda çalışmaz) istat komutu ve bunlarla işlem yapabileceğiniz bilgiler, örneğin:

LC_ALL=C istat "$file" | awk 'NR == 4 {print $5}'

( ayrıntıları anlamaya yardımcı olan @JeffSchaller için teşekkürler ).

tcsh içinde:

@ size = -Z $file:q

(sembolik çözünürlükten sonraki boyut)

GNU stat komutunu uygulamaya koymadan çok önce, GNU find komutu ile -printf Yüklem (zaten 1991'de):

find -- "$file" -Prune -printf '%s\n'    # st_size of file
find -L -- "$file" -Prune -printf '%s\n' # after symlink resolution

Ancak bir sorun, $file İle - Başlıyorsa veya find yüklemiyle (!, ( Gibi bir işe yaramazsa işe yaramaz. ..).

stat()/lstat() bilgisini almak için standart komut ls'dir.

POSIXly, şunları yapabilirsiniz:

LC_ALL=C ls -dn -- "$file" | awk '{print $5; exit}'

ve aynı sembol bağlantısı çözünürlüğünden sonra -L ekleyin. Bu cihaz dosyaları için işe yaramaz ama burada 5inci alanı, boyut yerine cihazın ana numarasıdır.

Blok cihazlar için, st_size İçin stat() ifadesinin 0 döndürdüğü sistemlerde, genellikle blok cihazın boyutunu bildirmek için başka API'lar bulunur. Örneğin, Linux'ta BLKGETSIZE64ioctl() vardır ve Linux dağıtımlarının çoğu artık bundan yararlanabilecek bir blockdev komutu ile gönderilir:

blockdev --getsize64 -- "$device_file"

Ancak bunun için aygıt dosyasına okuma izninizin olması gerekir. Boyutu başka yollarla türetmek genellikle mümkündür. Örneğin (hala Linux'ta):

lsblk -bdno size -- "$device_file"

Boş cihazlar dışında çalışmalıdır.

Tüm aranabilir dosyalar için çalışan bir yaklaşım (normal dosyaları, çoğu blok cihazı ve bazı karakter cihazlarını içerir) dosyayı açmak ve sonuna kadar aramaktır :

  • zsh ile (zsh/system Modülünü yükledikten sonra):

    {sysseek -w end 0 && size=$((systell(0)))} < $file
    
  • ksh93 İle:

    < "$file" <#((size=EOF))
    

    veya

    { size=$(<#((EOF))); } < "$file"
    
  • Perl ile:

    Perl -le 'seek STDIN, 0, 2 or die "seek: $!"; print tell STDIN' < "$file"
    

Adlandırılmış kanallar için, bazı sistemlerin (en azından AIX, Solaris, HP/UX) boru tamponundaki veri miktarını stat() 's st_size İçinde kullanılabilir hale getirdiklerini gördük. Bazıları (Linux veya FreeBSD gibi) yapmaz.

En azından Linux'ta, boruyu açtıktan sonra FIONREADioctl() kullanabilirsiniz (asılı kalmasını önlemek için okuma + yazma modunda):

fuser -s -- "$fifo_file" && 
  Perl -le 'require "sys/ioctl.ph";
            ioctl(STDIN, &FIONREAD, $n) or die$!;
            print unpack "L", $n' <> "$fifo_file"

Bununla birlikte, borunun içeriğini okumaz , ancak adlandırılmış borunun sadece açılmasının hala yan etkileri olabileceğini unutmayın. İlk önce bazı işlemlerin bunu hafifletmek için zaten borusu açık olup olmadığını kontrol etmek için fuser kullanıyoruz, ancak fuser tüm süreçleri kontrol edemeyebileceğinden bu kusursuz değildir.

Şimdiye kadar, yalnızca dosyalarla ilişkili birincil verilerin boyutunu ele alıyoruz. Bu, meta verilerin boyutunu ve bu dosyayı depolamak için gereken tüm destekleyici altyapıyı dikkate almaz.

stat() tarafından döndürülen başka bir inode özelliği st_blocks. Bu, dosyanın verilerini depolamak için kullanılan 512 baytlık blokların sayısıdır (ve bazen meta verilerinin bazıları, Linux'ta ext4 dosya sistemlerindeki genişletilmiş öznitelikler gibi). Bu, inode veya dosyanın bağlı olduğu dizinlerdeki girişleri içermez.

Boyut ve disk kullanımı, sıkıştırma, seyreklik (bazen bazı meta veriler), bazı dosya sistemlerindeki dolaylı bloklar gibi ekstra altyapının ikincisi üzerinde etkili olmasıyla sıkı sıkıya ilişkili değildir.

Disk kullanımını bildirmek için du genellikle bunu kullanır. Yukarıda listelenen komutların çoğu size bu bilgileri verebilir.

  • POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'
  • POSIXLY_CORRECT=1 du -s -- "$file" (İçindeki dosyaların disk kullanımını içeren dizinler için değil).
  • GNU find -- "$file" -printf '%b\n'
  • zstat -L +block -- $file
  • GNU stat -c %b -- "$file"
  • BSD stat -f %b -- "$file"
  • Perl -le 'print((lstat shift)[12])' -- "$file"
32

Bu komut dosyası, dosya boyutunu hesaplamanın birçok yolunu birleştirir:

(
  du --apparent-size --block-size=1 "$file" 2>/dev/null ||
  gdu --apparent-size --block-size=1 "$file" 2>/dev/null ||
  find "$file" -printf "%s" 2>/dev/null ||
  gfind "$file" -printf "%s" 2>/dev/null ||
  stat --printf="%s" "$file" 2>/dev/null ||
  stat -f%z "$file" 2>/dev/null ||
  wc -c <"$file" 2>/dev/null
) | awk '{print $1}'

Komut dosyası Linux, BSD, OSX, Solaris, SunOS vb. Gibi birçok Unix sisteminde çalışır.

Dosya boyutu bayt sayısını gösterir. Dosyanın, özel sıkıştırma veya özel seyrek alanlar veya ayrılmamış bloklar vb.Gibi tipik bir diskte kullandığı bayt olan görünür boyuttur.

Bu komut dosyasının burada daha fazla yardım ve daha fazla seçenek içeren bir üretim sürümü var: https://github.com/SixArm/file-size

22

stat bunu en az sistem çağrısı ile yapıyor gibi görünüyor:

$ set debian-live-8.2.0-AMD64-xfce-desktop.iso

$ strace stat --format %s $1 | wc
    282    2795   27364

$ strace wc --bytes $1 | wc
    307    3063   29091

$ strace du --bytes $1 | wc
    437    4376   41955

$ strace find $1 -printf %s | wc
    604    6061   64793
9
user150821

ls -l filename, bir dosya hakkında dosya boyutu, izinleri ve sahibi de dahil olmak üzere birçok bilgi verecektir.

Beşinci sütundaki dosya boyutu bayt cinsinden görüntülenir. Aşağıdaki örnekte, dosya boyutu 2 KB'ın hemen altındadır:

-rw-r--r-- 1 user owner 1985 2011-07-12 16:48 index.php

Edit: Görünüşe göre stat komutu kadar güvenilir değil.

8
Druckles

du filename disk kullanımını bayt cinsinden söyleyecektir.

Tercih ederim du -h filename, size insan tarafından okunabilir bir format verir.

5
Teddy

Bir AWK 1 astar buldum ve bir hata vardı ama düzelttim. TeraBytes'ten sonra PetaBytes'e de ekledim.

FILE_SIZE=234234 # FILESIZE IN BYTES
FILE_SIZE=$(echo "${FILE_SIZE}" | awk '{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }')

stat her sistemde olmadığından, neredeyse her zaman AWK çözümünü kullanabilirsiniz. Misal; Raspberry Pi'de stat yok ama awk var.

3
findrbot_admin

Shell komut dosyalarınızda temsilci atayabileceğiniz küçük yardımcı program işlevleri oluşturun.

Örnek

#! /bin/sh -
# vim: set ft=sh

# size utility that works on GNU and BSD systems
size(){
    case $(uname) in
        (Darwin | *BSD*)
            stat -Lf %z -- "$1";;
        (*) stat -c %s -- "$1"
    esac
}

for f do
    printf '%s\n' "$f : $(gzip < "$f" | wc -c) bytes (versus $(size "$f") bytes)"
done

@ Stéphane Chazelas'ın cevabındaki bilgilere dayanarak.

3
oligofren

POSIX uyumlu diğer bir yol, satırsonu karakterleri hariç, girdi dosyasının her satırındaki karakterlerde uzunluğu döndüren length() işleviyle awk kullanmaktır. Yani yaparak

awk '{ sum+=length } END { print sum+NR }' file

NR öğesinin sum öğesine eklendiğinden emin oluruz, böylece dosyada karşılaşılan toplam karakter sayısı ve toplam satır sayısı olur. awk içindeki length() işlevi, varsayılan olarak geçerli tüm satır için olan length($0) anlamına gelen bir argüman alır.

0
Inian