Bir bash betiğinde bir dosyanın boyutunu nasıl alabilirim?
Bunu daha sonra kullanabilmem için bir bash değişkenine nasıl atayabilirim?
pvve bununla eşleştirin cat:)
Bir bash betiğinde bir dosyanın boyutunu nasıl alabilirim?
Bunu daha sonra kullanabilmem için bir bash değişkenine nasıl atayabilirim?
pvve bununla eşleştirin cat:)
Yanıtlar:
Bir GNU sisteminde ise en iyi bahis:
stat --printf="%s" file.any
Gönderen adam, stat :
% s toplam boyut, bayt olarak
Bir bash betiğinde:
#!/bin/bash
FILENAME=/home/heiko/dummy/packages.txt
FILESIZE=$(stat -c%s "$FILENAME")
echo "Size of $FILENAME = $FILESIZE bytes."
NOT: stat'ı Mac OS X'te terminalde nasıl kullanacağınız için @ chbrown'un cevabına bakınız .
stat, Linux veya Cygwin kullandığınızı varsayarak ( statstandart değil) en kolay yoldur . Eugéne tarafından önerildiğiwc -c gibi taşınabilir.
stat: illegal option -- c
stat --printf="%s" file.txtDebian Jessie ile ilgili hiçbir şey çıkmadı ...
stat -f%z myfile.tar
man statdiyor ki - printf sondaki yeni satırı atlıyor. Çıkışı görmek için --formatveya -cdüğmesini kullanın . Karşılaştırarak daha fazla fikir stat --printf="%s" file.any | xxd -edinstat -c "%s" file.any | xxd -
file_size_kb=`du -k "$filename" | cut -f1`
Kullanmanın sorunu stat, bunun bir GNU (Linux) uzantısı olmasıdır. du -kve cut -f1POSIX tarafından belirtilmiştir ve bu nedenle herhangi bir Unix sistemine taşınabilir.
Örneğin, Solaris bash ile birlikte gelir ancak gemiyle birlikte gönderilmez stat. Yani bu tamamen varsayımsal değildir.
lsÇıktının tam formatının belirtilmemesinde de benzer bir problem vardır, bu yüzden çıktısının ayrıştırılması taşınabilir olarak yapılamaz. du -haynı zamanda bir GNU uzantısıdır.
Mümkün olan yerlerde taşınabilir yapılara bağlı kalın ve gelecekte birilerinin hayatını kolaylaştıracaksınız. Belki kendi
dudosyanın boyutunu vermez, dosyanın ne kadar alan kullandığına dair bir gösterge verir, bu incelikle farklıdır (genellikle bildirilen duboyut, en yakın blok sayısına kadar yuvarlanan dosyanın boyutudır, burada bir blok tipik olarak 512B veya 1kB veya 4kB'dir).
--bytesya da -bbunun yerine -k, kabul edilen cevap olmalıdır.
-h(Artık "insan") seçeneğidu genel durumlar için en uygun cevabı üretecek: file_size=`du -h "$filename" | cut -f1bu K (kilobayt), M (Megabyte) veya uygun şekilde G (Gigabayt) gösterecektir olarak.
"Word count" command ( wc) komutunu da kullanabilirsiniz :
wc -c "$filename" | awk '{print $1}'
Sorun wc, dosya adını eklemesi ve çıktının girintili çıkmasıdır. Örneğin:
$ wc -c somefile.txt
1160 somefile.txt
Yalnızca dosya boyutu sayımı elde etmek için tam bir çevrilmiş dil veya akış editörü zincirlemekten kaçınmak istiyorsanız, dosyadaki girdiyi wcasla görmeyecek şekilde dosyadan girdiyi yönlendirin :
wc -c < "$filename"
Bu son form, aşağıda Gilles tarafından belirtildiği gibi, bir kabuk değişkeni olarak aradığınız değeri kolayca almak için komut değiştirme ile kullanılabilir .
size="$(wc -c <"$filename")"
wc -c <"$FILENAME"Böylece, başka hiçbir sıkıntı olmadan boyutu verir size=$(wc -c <"$FILENAME").
wc -c < fileçok hızlı gözüküyorum, en azından OS X'de. Sadece -c belirtilmişse wc'nin dosyayı statülemeye çalışacak beyinleri olduğunu tahmin ediyorum.
wc -ckullanır fstat, ancak dosyanın ikinci son bloğunu arar ve en son st_blksizebaytları okur . Görünüşe bu Linux kullanıcısının dosyalar çünkü /procve /sysörneğin sadece yaklaşık değerlerdir istatistik boyutları vardır ve wcgerçek boyutu değil, istatistik bildirilen boyutu bildirmek istiyor. Sanırım wc -cfarklı bir boyutta rapor vermek garip olurdu wc, ancak normal bir disk dosyasıysa dosyadan veri okumak ve bellekte yoksa, bu bir fikir değildir. Ya da daha kötüsü, sıradaki kaset deposu ...
printfGirintiyi hala görüyor gibi görünüyor , örneğin printf "Size: $size"-> size: <4 spaces> 54339. Diğer yandan echoboşlukları görmezden geliyor. Tutarlı kılmanın bir yolu var mı?
fstat. Koşmayı deneyin strace wc -c </etc/passwdve ne yaptığını görebilirsiniz.
BSD'ler (Mac OS X'ler) statfarklı bir format argüman bayrağına ve farklı alan belirleyicilerine sahiptir. Kimden man stat(1):
-f format: Belirtilen formatı kullanarak bilgileri görüntüleyin. Geçerli formatların bir açıklaması için FORMATLAR bölümüne bakın.z: Dosyanın bayt olarak boyutu.Şimdi hep birlikte:
stat -f%z myfile1.txt
Derken ne demek istediğine bağlıdır boyutu .
size=$(wc -c < "$file")
Size dosyadan okunabilecek bayt sayısını verecektir. IOW, dosya içeriğinin boyutudur. Bununla birlikte, dosyanın içeriğini okuyacaktır (dosyanın çoğu wcuygulamada bir optimizasyon olarak normal bir dosya veya düzenli dosyaya bağlanması dışında ). Bunun yan etkileri olabilir. Örneğin, bir adlandırılmış boru ne okundu artık tekrar okunabilir ve benzeri şeyler için /dev/zeroya /dev/randomsonsuz büyüklüktedir, bir süre alacak. Bu da readdosyaya izin vermeniz gerektiği anlamına gelir ve dosyanın son erişim zaman damgası güncellenebilir.
Bu standart ve portatiftir, ancak bazı wcuygulamaları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 boş bir aritmetik ifadeyle ilgili dashveya hiç çıktı üretmediği yashzamanki bir hatayı önlemek için wc(örneğin, dosya açılamadığında):
size=$(($(wc -c < "$file") +0))
ksh93olan wcyerleşik (alabilmesi sağlanır, ayrıca olarak çağırabilir command /opt/ast/bin/wco kabukta düzenli dosyalar için en verimli kılan).
Çeşitli sistemler adı verilen bir komutu var statbir arayüzü stat()veya lstat()sistem çağrıları.
Bu bilgi inode'da bulundu. Bu bilgilerden biri st_sizeözelliktir. Düzenli dosyalar için, içeriğin boyutu (hata yokluğunda ondan ne kadar veri okunabileceği ( wc -cuygulamaların çoğunun optimizasyonunda kullandığı şey )) budur. Sembolik bağlantılarda hedef yolun bayt cinsinden boyutudur. Adlandırılmış borular için, sisteme bağlı olarak, ya 0 ya da şu anda boru arabelleğindeki bayt sayısıdır. Sisteme bağlı olarak, 0 veya temel alınan depolamanın bayt cinsinden boyutunu aldığınız blok cihazlar için aynıdır.
Bu bilgiyi almak için dosyaya okuma iznine ihtiyacınız yoktur, yalnızca bağlı olduğu dizine arama iznini verin.
Kronolojik sıraya göre, var:
IRIXstat (90'lar):
stat -qLs -- "$file"
( ) veya st_sizeözniteliğini döndürür :$filelstat()
stat -s -- "$file"
Aynı zamanda $file, ne zaman bir sembolik link ise, bu durumda st_sizesembolik link çözünürlüğünden sonraki dosyanın kendisidir.
zsh statyerleşik (şimdi olarak da bilinir zstat) zsh/statmodülde (yüklü 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 kabukta en verimli olanı.
GNUstat (2001); ayrıca stat2005'ten beri BusyBox'ta ( GNU'dan kopyalanmıştır stat):
stat -c %s -- "$file" # st_size of file
stat -Lc %s -- "$file" # after symlink resolution
( -LIRIX veya ile karşılaştırıldığında anlamının tersine dikkat edin zsh stat.
BSD'lerstat (2002):
stat -f %z -- "$file" # st_size of file
stat -Lf %z -- "$file" # after symlink resolution
Veya aşağıdaki gibi bir betik dili stat()/ lstat()işlevini kullanabilirsiniz perl:
perl -le 'print((lstat shift)[7])' -- "$file"
AIX ayrıca tüm (örneğin , sembolik bağlantılar üzerinde çalışmayacak) bilgisini silen ve sonradan işlem yapabileceğiniz bir istatkomut içerir, örneğin:stat()lstat()
LC_ALL=C istat "$file" | awk 'NR == 4 {print $5}'
(Ayrıntıları bulmak için yardım için @JeffSchaller teşekkürler ).
İçinde tcsh:
@ size = -Z $file:q
(bağlantı noktasının çözünürlüğünden sonraki boyut)
GNU statemrini vermeden çok önce , aynısı onun emri ile GNU findemri ile başarılabilirdi -printf(zaten 1991'de):
find -- "$file" -prune -printf '%s\n' # st_size of file
find -L -- "$file" -prune -printf '%s\n' # after symlink resolution
Yine de bir mesele, $fileşununla başladığında -ya da bir findyüklem ise işe yaramamasıdır (gibi !, (...).
stat()/ lstat()Bilgi almak için standart komuttur ls.
POSIXly şunları yapabilirsiniz:
LC_ALL=C ls -dn -- "$file" | awk '{print $5; exit}'
ve -Laynı bağlantı sembolik çözünürlükten sonra ekleyin . Bu, 5. dosyalar alanın büyüklüğü yerine cihazın büyük sayısı olduğu halde cihaz dosyaları için işe yaramaz .
Blok cihazlar stat()için st_size, 0 döndüren sistemler , genellikle blok cihazın boyutunu bildirmek için başka API'lere sahiptir. Örneğin, Linux BLKGETSIZE64 ioctl(), ve çoğu Linux dağıtımında artık blockdevbunu kullanabilecek bir komutla geliyor:
blockdev --getsize64 -- "$device_file"
Ancak bunun için cihaz dosyasına okuma iznine ihtiyacınız var. 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ı.
Aranabilir tüm dosyalar için geçerli olan bir yaklaşım (normal dosyalar, çoğu blok ve bazı karakter aygıtları içerir) dosyayı açıp sonuna kadar aramaktır:
İle zsh( zsh/systemmodülü yükledikten sonra ):
{sysseek -w end 0 && size=$((systell(0)))} < $fileİle ksh93:
< "$file" <#((size=EOF))
veya
{ size=$(<#((EOF))); } < "$file"ile perl:
perl -le 'seek STDIN, 0, 2 or die "seek: $!"; print tell STDIN' < "$file"Adlandırılmış borular için, bazı sistemlerin (en azından AIX, Solaris, HP / UX) boru tamponundaki veri miktarını stat()'lerde mevcut kıldığını gördük st_size. Bazıları (Linux veya FreeBSD gibi) yoktur.
En azından Linux'ta FIONREAD ioctl()boruyu açtıktan sonra kullanabilirsiniz (asılı kalmamak 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"
Ancak gelmez ise dikkat okumak borunun içeriği, burada adlandırılmış borunun sadece açılış hala yan etkileri olabilir. Öncelikle fuserbazı işlemlerin boruyu hafifletmek için zaten açık olduğunu kontrol etmek için kullanıyoruz , ancak fusertüm işlemleri kontrol edemeyeceği için kusursuz değildir.
Şimdiye kadar, yalnızca dosyalarla ilişkili birincil verilerin boyutunu düşünüyoruz . Bu, meta verilerin boyutunu ve bu dosyayı depolamak için gereken tüm destek altyapısını dikkate almaz.
Tarafından döndürülen bir başka inode niteliği stat()olduğunu st_blocks. Bu, dosyanın verilerini depolamak için kullanılan 512 bayt blok sayısıdır (bazen Linux'ta ext4 dosya sistemindeki genişletilmiş öznitelikler gibi meta verilerinden bazıları). Bu inode kendisini veya dosyanın bağlandığı dizinlerdeki girişleri içermez.
Boyut ve disk kullanımı mutlaka sıkıştırma, seyreklik (bazen bazı meta veriler), bazı dosya sistemlerinde dolaylı bloklar gibi ekstra altyapıların ikincisi üzerinde etkisi olur.
Bu genellikle dudisk kullanımını bildirmek için kullanılan şeydir . Yukarıda listelenen komutların çoğu size bu bilgiyi verebilir.
POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'POSIXLY_CORRECT=1 du -s -- "$file" (bunun içindeki dosyaların disk kullanımını içereceği dizinler için değil).find -- "$file" -printf '%b\n'zstat -L +block -- $filestat -c %b -- "$file"stat -f %b -- "$file"perl -le 'print((lstat shift)[12])' -- "$file"wc -ckullanıyor fstat, ancak sonuncu st_blksizebaytları okuyor . Görünüşe göre bunun nedeni Linux'lardaki /procve /sysörneğin dosyaların yalnızca yaklaşık olan stat boyutlarına sahip olmasıdır . Bu doğruluk için iyidir, ancak dosyanın sonu diskte ise ve bellekte değilse (özellikle bir döngüdeki birçok dosyada kullanılıyorsa) kötüdür. Dosya çok yakın bir bant deposuna veya örneğin bir FUSE şeffaf-dekompresyon dosya sistemine geçirilirse çok kötü .
ls -go file | awk '{print $3}'
-gobunlar SysV olanlar olacak, BSD'ler (POSIX'de isteğe bağlı (XSI)) üzerinde çalışmayacaklardı. Ayrıca ls -god file | awk '{print $3; exit}'( -ddizinlerde çalışması exit, hedefe yeni satırları olan sembolik bağlantılar için) de ihtiyacınız olacaktı . Cihaz dosyalarındaki sorunlar da devam etmektedir.
wc -cbayt sayısını bildirmez.
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}'
Betik Linux, BSD, OSX, Solaris, SunOS vb. Dahil olmak üzere birçok Unix sisteminde çalışır.
Dosya boyutu bayt sayısını gösterir. Özel sıkıştırma veya özel seyrek alanlar veya ayrılmamış bloklar, vb.
Bu betiğin burada daha fazla yardım ve daha fazla seçenek içeren bir üretim sürümü var: https://github.com/SixArm/file-size
stat bunu en az sistem çağrısıyla 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
ls -l filename dosya boyutu, izinleri ve sahibi de dahil olmak üzere bir dosya hakkında size birçok bilgi verecektir.
Beşinci sütundaki dosya boyutu ve bayt olarak görüntülenir. Aşağıdaki örnekte, dosya boyutu 2KB'nin altında:
-rw-r--r-- 1 user owner 1985 2011-07-12 16:48 index.php
Düzenleme: Bu görünüşte statkomut kadar güvenilir değil .
ls -lve statgüvenilir boyut bilgi vermek emrediyorum. Aksine hiçbir referans bulamadım. ls -sblok sayısında boyut verecektir.
du filename bayt cinsinden disk kullanımını anlatacağım.
Size du -h filename, okunabilir bir formatta boyut veren, tercih ediyorum .
dubasit bir bayt sayısı değil, 1024 baytlık bloklar halinde yazdırılır.
du512 bayt birim sayısı verdiğini unutmayın . GNU du, ortamında çağrılmadığı sürece kibibitler kullanır POSIXLY_CORRECT.
Kabuk komut dosyalarınızda yetki verebileceğiniz küçük yardımcı işlevler 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 bilgiye dayanarak.
gzip -v < file > /dev/nullBir dosyanın sıkıştırılabilirliğini kontrol etmek için ayrıca bakınız .
caseifade kullanmak isteyeceğiniz tipik bir durum var . caseBourne / POSIX yapısı desen eşleştirmesidir. [[...]]sadece ksh / bash / zsh'dir (varyasyonlarla).
Bir AWK 1 astar buldum ve bir böcek vardı ama tamir ettim. Ayrıca TeraBytes'den 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] }')
Düşünüldüğünde , stat her sistemde değil, hemen hemen her zaman AWK çözümü kullanabilirsiniz. Örnek; Ahududu Pi stat yok ama awk var .
Başka bir POSIX uyumlu yol , yeni satır karakterleri hariç olmak üzere girdi dosyasının her satırındaki karakterlerde uzunluğu döndüren işlevi awkile birlikte kullanmaktır length(). Yani yaparak
awk '{ sum+=length } END { print sum+NR }' file
Biz sağlamak NReklenir sumve böylece karakterler ve dosyadaki karşılaşılan satırsonlarının toplam sayısının toplam sayısı sonuçlanan. length()İşlev awkvarsayılan vasıtasıyla bir argüman hangi sürer length($0)geçerli bütün hat içindir.
printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'3 ama baskılar 4. yazdırmalısınız
Wc seçeneğini kendim seviyorum. 'Bc' ile eşleştirildiğinde, dilediğiniz sayıda yere ondalık alabilirsiniz.
Bir 'ls -alh' komutunun 'dosya boyutu' sütununu uyandırdığım bir komut dosyasını geliştirmek istiyordum. Tamsayı dosya boyutlarını istemedim ve iki ondalık sayı uygun görünüyordu, bu yüzden bu tartışmayı okuduktan sonra aşağıdaki kodu buldum.
Bunu bir komut dosyasına dahil ederseniz, noktalı virgüllerde çizgiyi kesmenizi öneririm.
file=$1; string=$(wc -c $file); bite=${string% *}; okay=$(echo "scale=2; $bite/1024" | bc);friend=$(echo -e "$file $okay" "kb"); echo -e "$friend"
Komut dosyama "resim dosyası uzunluğu almak" için gpfl adı verilir . Bir görüntüyü bir GUI jpeg görüntüleyicide açmadan ya da yeniden yüklemeden önce, imagemagick'deki bir dosyada sıkıntı yaptıktan sonra kullanırım .
Bu oranların nasıl bir "cevap" olarak bilmiyorum, çünkü teklif edilmiş ve tartışılmış olanlardan çok ödünç alıyor. Bu yüzden orada bırakacağım.
BZT
wcolması durumunda stat.st_size(Linux /procve /sysdosyalar için olduğu gibi) dosyanın son satırını okuduğunu unutmayın . Sanırım bu mantığı bir kaç satır daha eklediklerinde ana yorumu daha karmaşık hale getirmemeye karar verdiler: lingrok.org/xref/coreutils/src/wc.c#246
En hızlı ve en basit (IMO) yöntemi şudur:
bash_var=$(stat -c %s /path/to/filename)
duve wcyanıt hakkında şikayet edebilirim . Bu gece cevabımı gerçek bir yaşam uygulamasında kullandım ve paylaşımın faydalı olacağını düşündüm. Sanırım hepimizin omuzlarını silkiyoruz .