@ haunted85 statadalah cara yang paling mudah, dengan asumsi Anda menggunakan Linux atau Cygwin ( statbukan standar). wc -cseperti yang disarankan oleh Eugéne portabel.
Gilles
2
stat: illegal option -- c
Iulian Onofrei
stat --printf="%s" file.txttidak menampilkan apa pun di Debian Jessie ...
woohoo
5
Pada MacOS ini berfungsi:stat -f%z myfile.tar
ccpizza
2
@woohoo Prompt Anda menimpa output. man statmengatakan bahwa - printf menghilangkan baris baru yang tertinggal. Gunakan --formatatau -cuntuk melihat hasilnya. Mendapatkan wawasan yang lebih dengan membandingkan stat --printf="%s" file.any | xxd -kestat -c "%s" file.any | xxd -
cucu
92
file_size_kb=`du -k "$filename" | cut -f1`
Masalah dengan penggunaan statadalah bahwa itu adalah ekstensi GNU (Linux). du -kdan cut -f1ditentukan oleh POSIX dan karenanya portabel untuk sistem Unix apa pun.
Solaris, misalnya, kapal dengan pesta tapi tidak dengan stat. Jadi ini tidak sepenuhnya hipotetis.
lsmemiliki masalah yang sama dalam format output yang tepat tidak ditentukan, sehingga penguraian output tidak dapat dilakukan dengan mudah. du -hjuga merupakan ekstensi GNU.
Tetap gunakan konstruksi portabel jika memungkinkan, dan Anda akan membuat hidup seseorang lebih mudah di masa depan. Mungkin milikmu sendiri.
dutidak memberikan ukuran file, itu memberikan indikasi berapa banyak ruang file menggunakan, yang agak berbeda (biasanya ukuran yang dilaporkan oleh duadalah ukuran file dibulatkan ke jumlah blok terdekat, di mana sebuah blok biasanya 512B atau 1kB atau 4kB).
Gilles
7
@Gilles, file jarang (yaitu yang berlubang) melaporkan kurang dari panjangnya.
vonbrand
5
Ini, dengan --bytesatau -balih-alih -k, harus menjadi jawaban yang diterima.
Amedee Van Gasse
1
Opsi -h("manusia") daridu akan menghasilkan jawaban yang paling tepat untuk kasus umum:, file_size=`du -h "$filename" | cut -f1karena akan menampilkan K (kilobyte), M (Megabytes) atau G (Gigabytes) yang sesuai.
fralau
1
@fralau: OP ingin "menetapkan ini ke variabel bash sehingga mereka dapat menggunakannya nanti", jadi jauh lebih mungkin mereka menginginkan nilai numerik yang sebenarnya, bukan perkiraan yang dapat dibaca manusia. Juga, -hadalah ekstensi GNU; itu tidak standar
Nemo
74
Anda juga dapat menggunakan perintah "jumlah kata" ( wc):
wc -c "$filename"| awk '{print $1}'
Masalahnya wcadalah ia akan menambahkan nama file dan membuat indentasi hasilnya. Sebagai contoh:
$ wc -c somefile.txt
1160 somefile.txt
Jika Anda ingin menghindari chaining bahasa yang ditafsirkan penuh atau editor aliran hanya untuk mendapatkan jumlah ukuran file, cukup arahkan kembali input dari file sehingga wctidak pernah melihat nama file:
wc -c <"$filename"
Formulir terakhir ini dapat digunakan dengan substitusi perintah untuk dengan mudah mengambil nilai yang Anda cari sebagai variabel shell, seperti yang disebutkan oleh Gilles di bawah ini.
wc -c <"$FILENAME"memberikan ukuran tanpa cruft lainnya, dengan demikian size=$(wc -c <"$FILENAME").
Gilles
6
Hanya satu poin lagi: Saya baru saja mengujinya dan wc -c < filetampaknya sangat cepat, setidaknya pada OS X. Saya menduga bahwa wc memiliki otak untuk mencoba membuat stat file jika hanya -c yang ditentukan.
Edward Falk
4
@ EdwardFalk: GNU wc -cmenggunakan fstat, tetapi kemudian mencari blok kedua-terakhir dari file dan membaca st_blksizebyte terakhir yang up-to . Rupanya ini karena file di Linux /procdan /sysmisalnya memiliki ukuran stat yang hanya perkiraan , dan wcingin melaporkan ukuran sebenarnya, bukan ukuran yang dilaporkan stat. Saya kira itu akan aneh untuk wc -cmelaporkan ukuran yang berbeda dari wc, tetapi itu bukan ide untuk membaca data dari file jika itu adalah file disk yang normal, dan itu tidak ada dalam memori. Atau lebih buruk, penyimpanan tape dekat-line ...
Peter Cordes
1
Sepertinya printfmasih melihat lekukan, misalnya printf "Size: $size"-> size: <4 spaces> 54339. Di sisi lain echomengabaikan spasi. Adakah cara untuk membuatnya konsisten?
Eugene Kulabuhov
2
@keithpjolley: Dengan menelepon fstat. Coba jalankan strace wc -c </etc/passwddan Anda dapat melihat apa yang dilakukannya.
Nemo
48
BSD (Mac OS X) statmemiliki flag argumen format yang berbeda, dan penentu lapangan yang berbeda. Dari man stat(1):
-f format: Menampilkan informasi menggunakan format yang ditentukan. Lihat bagian FORMAT untuk deskripsi format yang valid.
akan memberi Anda jumlah byte yang dapat dibaca dari file. TKI, itu ukuran isi file. Namun ia akan membaca isi file (kecuali jika file tersebut adalah file biasa atau symlink ke file biasa di sebagian besar wcimplementasi sebagai optimasi). Itu mungkin memiliki efek samping. Misalnya, untuk pipa bernama, apa yang telah dibaca tidak dapat lagi dibaca lagi dan untuk hal-hal seperti /dev/zeroatau /dev/randomyang berukuran tak terbatas, itu akan memakan waktu cukup lama. Itu juga berarti Anda memerlukan readizin untuk file tersebut, dan cap waktu akses terakhir dari file tersebut dapat diperbarui.
Itu standar dan portabel, namun perlu dicatat bahwa beberapa wcimplementasi mungkin termasuk memimpin kosong dalam output itu. Salah satu cara untuk menghilangkannya adalah dengan menggunakan:
size=$(($(wc -c <"$file")))
atau untuk menghindari kesalahan tentang ekspresi aritmatika kosong di dashatau yashsaat wctidak menghasilkan keluaran (seperti saat file tidak dapat dibuka):
size=$(($(wc -c <"$file")+0))
ksh93memiliki wcbuiltin (asalkan Anda mengaktifkannya, Anda juga dapat memanggilnya sebagai command /opt/ast/bin/wc) yang membuatnya paling efisien untuk file biasa di shell itu.
Berbagai sistem memiliki perintah yang disebut statantarmuka untuk panggilan sistem stat()atau lstat().
Informasi laporan tersebut ditemukan dalam inode. Salah satu informasi itu adalah st_sizeatribut. Untuk file biasa, itu ukuran konten (seberapa banyak data dapat dibaca dari itu tanpa adanya kesalahan (itulah yang sebagian besar wc -cimplementasi digunakan dalam optimasi mereka)). Untuk symlink, itu ukuran dalam byte dari jalur target. Untuk pipa bernama, tergantung pada sistem, itu 0 atau jumlah byte saat ini di buffer pipa. Sama untuk perangkat blok di mana tergantung pada sistem, Anda mendapatkan 0 atau ukuran dalam byte penyimpanan yang mendasarinya.
Anda tidak perlu izin baca ke file untuk mendapatkan informasi itu, hanya izin pencarian ke direktori yang ditautkan.
stat -f %z --"$file"# st_size of file
stat -Lf%z --"$file"# after symlink resolution
Atau Anda dapat menggunakan stat()/ lstat()fungsi beberapa bahasa scripting seperti perl:
perl -le 'print((lstat shift)[7])'--"$file"
AIX juga memiliki istatperintah yang akan membuang semua informasi stat()(tidak lstat(), jadi tidak akan bekerja pada symlinks) dan yang dapat Anda posting setelahnya, misalnya:
Jauh sebelum GNU memperkenalkan statperintahnya, hal yang sama dapat dicapai dengan findperintah GNU dengan -printfpredikatnya (sudah pada tahun 1991):
find --"$file"-prune -printf '%s\n'# st_size of file
find -L --"$file"-prune -printf '%s\n'# after symlink resolution
Namun satu masalah adalah itu tidak berfungsi jika $filedimulai dengan -atau merupakan findpredikat (seperti !, (...).
Perintah standar untuk mendapatkan stat()/ lstat()informasi adalah ls.
POSIXly, Anda dapat melakukan:
LC_ALL=C ls -dn --"$file"| awk '{print $5; exit}'
dan tambahkan -Luntuk resolusi symlink yang sama setelah. Itu tidak berfungsi untuk file perangkat meskipun di mana bidang ke- 5 adalah nomor utama perangkat, bukan ukurannya.
Untuk perangkat blok, sistem tempat stat()pengembalian 0 untuk st_size, biasanya memiliki API lain untuk melaporkan ukuran perangkat blok. Sebagai contoh, Linux memiliki BLKGETSIZE64ioctl(), dan sebagian besar distribusi Linux sekarang dikirimkan dengan blockdevperintah yang dapat memanfaatkannya:
blockdev --getsize64 --"$device_file"
Namun, Anda perlu izin baca ke file perangkat untuk itu. Biasanya dimungkinkan untuk mendapatkan ukuran dengan cara lain. Misalnya (masih di Linux):
lsblk -bdno size --"$device_file"
Seharusnya berfungsi kecuali untuk perangkat kosong.
Pendekatan yang berfungsi untuk semua file yang dapat dicari (termasuk file biasa, sebagian besar perangkat blok dan beberapa perangkat karakter) adalah membuka file dan mencari sampai akhir:
Dengan zsh(setelah memuat zsh/systemmodul):
{sysseek -w end 0&& size=$((systell(0)))}< $file
Dengan ksh93:
<"$file"<#((size=EOF))
atau
{ size=$(<#((EOF)));}<"$file"
dengan perl:
perl -le 'seek STDIN, 0, 2 or die "seek: $!"; print tell STDIN'<"$file"
Untuk pipa bernama, kita telah melihat bahwa beberapa sistem (AIX, Solaris, HP / UX setidaknya) membuat jumlah data dalam buffer pipa yang tersedia di stat()'s st_size. Beberapa (seperti Linux atau FreeBSD) tidak.
Di Linux setidaknya, Anda dapat menggunakan FIONREADioctl()setelah membuka pipa (dalam mode baca + tulis untuk menghindari menggantung):
Namun perhatikan bahwa sementara itu tidak membaca konten pipa, pembukaan pipa yang dinamai di sini masih dapat memiliki efek samping. Kami menggunakan fuseruntuk memeriksa terlebih dahulu bahwa beberapa proses sudah memiliki pipa terbuka untuk meringankan itu tetapi itu tidak mudah karena fusermungkin tidak dapat memeriksa semua proses.
Sekarang, sejauh ini kami hanya mempertimbangkan ukuran data primer yang terkait dengan file. Itu tidak memperhitungkan ukuran metadata dan semua infrastruktur pendukung yang diperlukan untuk menyimpan file itu.
Atribut inode lain yang dikembalikan oleh stat()adalah st_blocks. Itu adalah jumlah blok 512 byte yang digunakan untuk menyimpan data file (dan terkadang beberapa metadata-nya seperti atribut yang diperluas pada sistem file ext4 di Linux). Itu tidak termasuk inode itu sendiri, atau entri dalam direktori file yang ditautkan.
Ukuran dan penggunaan disk tidak selalu terkait erat seperti kompresi, sparseness (kadang-kadang beberapa metadata), infrastruktur tambahan seperti blok tidak langsung di beberapa sistem file memiliki pengaruh pada yang terakhir.
Itulah yang biasanya dudigunakan untuk melaporkan penggunaan disk. Sebagian besar perintah yang tercantum di atas akan dapat memberi Anda informasi itu.
POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'
POSIXLY_CORRECT=1 du -s -- "$file" (bukan untuk direktori di mana itu termasuk penggunaan disk dari file-file di dalamnya).
jelas jawaban yang paling komprehensif dan informatif. Terima kasih. saya dapat menggunakan ini untuk membuat skrip bash lintas platform menggunakan BSD dan info statistik GNU
oligofren
1
Fakta menyenangkan: GNU coreutils wc -cdigunakan fstat, tetapi kemudian membaca st_blksizebyte terakhir yang terakhir . Rupanya ini karena file di Linux /procdan /sysmisalnya memiliki ukuran stat yang hanya perkiraan . Ini bagus untuk kebenaran, tetapi buruk jika ujung file ada di disk dan tidak ada di memori (khususnya jika digunakan pada banyak file dalam satu lingkaran). Dan sangat buruk jika file dimigrasi ke penyimpanan tape dekat-line , atau misalnya sistem file FUSE transparan-dekompresi.
Peter Cordes
tidak akan berhasills -go file | awk '{print $3}'
Steven Penny
@StevenPenny itu -goadalah yang SysV, mereka tidak akan bekerja pada BSD (opsional (XSI) di POSIX). Anda juga perlu ls -god file | awk '{print $3; exit}'( -dagar dapat bekerja pada direktori, exituntuk symlink dengan baris baru di target). Masalah dengan file perangkat juga tetap ada.
Stéphane Chazelas
1
@ αғsнιη API Unix tidak membuat perbedaan antara teks dan file biner. Itu semua urutan byte. Beberapa aplikasi mungkin ingin menginterpretasikan byte tersebut sebagai teks tetapi jelas bukan wc -cyang melaporkan jumlah byte.
Stéphane Chazelas
22
Script ini menggabungkan banyak cara untuk menghitung ukuran file:
Skrip ini berfungsi pada banyak sistem Unix termasuk Linux, BSD, OSX, Solaris, SunOS, dll.
Ukuran file menunjukkan jumlah byte. Ini adalah ukuran yang jelas, yaitu byte yang digunakan file pada disk biasa, tanpa kompresi khusus, atau area jarang khusus, atau blok yang tidak terisi, dll.
Saya pikir keduanya ls -ldan statperintah memberikan informasi ukuran yang dapat diandalkan. Saya tidak menemukan referensi yang bertentangan. ls -sakan memberikan ukuran dalam jumlah blok.
dabest1
2
@ dabest1 itu tidak dapat diandalkan dalam arti bahwa di unix lain, outputnya bisa berbeda (dan dalam beberapa unix itu).
Eugene Bujak
Ya, IIRC, Solaris tidak menampilkan nama grup secara default, menyebabkan lebih sedikit kolom di output.
Edward Falk
Karena ukurannya adalah numerik murni, dikelilingi oleh spasi putih, dan tahun tanggal adalah numerik murni, dalam format yang ditentukan, dimungkinkan untuk menggunakan regexp untuk memperlakukan pengguna + pemilik sebagai satu bidang, terlepas dari apakah grup tersebut ada atau tidak. (latihan untuk pembaca!)
MikeW
5
du filename akan memberi tahu Anda penggunaan disk dalam byte.
Saya lebih suka du -h filename, yang memberi Anda ukuran dalam format yang dapat dibaca manusia.
Rasa ini dumencetak ukuran dalam blok 1024 byte, bukan hitungan sederhana byte.
Peter Lyons
Perhatikan bahwa standar dumemberikan output dalam jumlah unit 512-byte. GNU dumenggunakan kibibytes sebagai gantinya kecuali dipanggil dengan POSIXLY_CORRECTdi lingkungannya.
Stéphane Chazelas
1
Untuk file bertipe direktori , yang memberikan penggunaan disk pada direktori tetapi juga semua file lainnya di dalamnya (secara rekursif).
Stéphane Chazelas
3
Buat fungsi utilitas kecil di skrip shell yang dapat Anda delegasikan.
Contoh
#! /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
Berdasarkan info dari jawaban @ Stéphane Chazelas.
@ StéphaneChazelas tidak yakin apakah saya pikir itu peningkatan. pernyataan kasus tersebut dapat dengan mudah menunda noobs; Saya tentu tidak pernah ingat bagaimana memperbaikinya :-) adakah pernyataan kasus secara inheren lebih portabel sejak Anda melakukannya? saya mengerti maksudnya ketika ada lebih dari dua kasus, tetapi sebaliknya ... +
oligofren
1
Saya kira itu juga masalah selera, tapi di sini adalah kasus khas di mana Anda ingin menggunakan casepernyataan. caseadalah konstruk Bourne / POSIX untuk melakukan pencocokan pola. [[...]]hanya ksh / bash / zsh (dengan variasi).
Stéphane Chazelas
2
Saya menemukan liner AWK 1, dan ada bug tetapi saya memperbaikinya. Saya juga menambahkan PetaBytes setelah TeraBytes.
Mengingat stat tidak ada di setiap sistem, Anda hampir selalu dapat menggunakan solusi AWK. Contoh; Raspberry Pi tidak memiliki stat tetapi memiliki awk .
Benar-benar BUKAN apa yang diminta OP, tapi sedikit pekerjaan yang bagus.
Gypsy Spellweaver
0
Satu cara lain yang sesuai dengan POSIX adalah menggunakan awkdengan length()fungsinya yang mengembalikan panjang, dalam karakter pada setiap baris dari file input, tidak termasuk karakter baris baru. Jadi dengan melakukan
awk '{ sum+=length } END { print sum+NR }' file
kami memastikan NRditambahkan ke sum, sehingga menghasilkan jumlah total karakter dan jumlah baris baru yang ditemui dalam file. The length()fungsi dalam awkmengambil sebuah argumen yang dengan cara standar length($0)yang untuk seluruh baris saat ini.
Tidak jika baris terakhir tidak berakhir pada baris baru: printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'harus mencetak 3 tetapi mencetak 4.
Isaac
-1
Saya suka opsi wc sendiri. Dipasangkan dengan 'bc,' Anda bisa mendapatkan desimal ke tempat sebanyak yang Anda mau.
Saya sedang mencari cara untuk memperbaiki skrip yang telah saya buat di kolom 'ukuran file' dari perintah 'ls -alh'. Saya tidak ingin hanya ukuran file integer, dan dua desimal sepertinya cocok, jadi setelah membaca diskusi ini, saya datang dengan kode di bawah ini.
Saya sarankan melanggar garis di titik koma jika Anda memasukkan ini dalam naskah.
Script saya disebut gpfl , untuk "dapatkan panjang file gambar." Saya menggunakannya setelah melakukan mogrify pada file di imagemagick, sebelum membuka atau memuat ulang gambar di GUI jpeg viewer.
Saya tidak tahu bagaimana ini menilai sebagai "jawaban," karena meminjam banyak dari apa yang sudah ditawarkan dan dibahas. Jadi saya akan meninggalkannya di sana.
Saya lebih suka menggunakan "stat" atau "ls". Biasanya saya tidak suka menggunakan "wc" untuk mendapatkan ukuran file karena secara fisik membaca seluruh file. Jika Anda memiliki banyak file, atau terutama file besar, ini bisa memakan banyak waktu. Tetapi solusi Anda kreatif ... + 1.
Kevin Fegan
2
Saya setuju dengan gagasan menggunakan "stat" di atas "wc" untuk filesize, namun jika Anda menggunakan "wc -c", tidak ada data yang akan dibaca; sebagai gantinya lseek akan digunakan untuk mencari tahu jumlah byte dalam suatu file. lingrok.org/xref/coreutils/src/wc.c#228
bbaja42
1
@ bbaja42: perhatikan bahwa GNU Coreutils wctidak membaca blok terakhir dari file, seandainya stat.st_sizehanya perkiraan (seperti untuk Linux /procdan /sysfile). Saya kira mereka memutuskan untuk tidak membuat komentar utama lebih rumit ketika mereka menambahkan logika itu beberapa baris ke bawah: lingrok.org/xref/coreutils/src/wc.c# 246
Peter Cordes
-1
Metode tercepat dan paling sederhana (IMO) adalah:
Kemudian, pilih satu atau lebih jawaban yang ada yang menyebutkan stat; tidak perlu mengulanginya lagi ...
Jeff Schaller
1
@ Jeffffaller Saya baru saja mengangkat jawaban Stephane atas instruksi Anda. Saya pikir itu terlalu rumit untuk tujuan saya. Itulah sebabnya saya memposting jawaban sederhana ini untuk jiwa-jiwa yang berpikiran sama.
WinEunuuchs2Unix
1
Terima kasih; hanya saja contoh keenam dari jawaban "stat" tidak menyederhanakan T&J ini, tetapi lebih suka membuat pembaca baru bertanya pada diri sendiri "bagaimana jawaban ini berbeda dari yang lain?" dan menyebabkan lebih banyak kebingungan bukannya kurang.
Jeff Schaller
@ Jeffffchaller kurasa. Tapi saya bisa mengeluh tentang banyak dudan wcjawaban yang harus memiliki penafian TIDAK PERNAH MELAKUKANNYA dalam kehidupan nyata. Saya hanya menggunakan jawaban saya dalam aplikasi kehidupan nyata malam ini dan berpikir itu layak untuk dibagikan. Saya kira kita semua memiliki pendapat kami mengangkat bahu .
pv
dancat
untuk perintah salin yang menunjukkan progres dan ETA :)Jawaban:
Taruhan terbaik Anda jika pada sistem GNU:
Dari man stat :
Dalam skrip bash:
CATATAN: lihat jawaban @ chbrown untuk cara menggunakan terminal stat in pada Mac OS X.
sumber
stat
adalah cara yang paling mudah, dengan asumsi Anda menggunakan Linux atau Cygwin (stat
bukan standar).wc -c
seperti yang disarankan oleh Eugéne portabel.stat: illegal option -- c
stat --printf="%s" file.txt
tidak menampilkan apa pun di Debian Jessie ...stat -f%z myfile.tar
man stat
mengatakan bahwa - printf menghilangkan baris baru yang tertinggal. Gunakan--format
atau-c
untuk melihat hasilnya. Mendapatkan wawasan yang lebih dengan membandingkanstat --printf="%s" file.any | xxd -
kestat -c "%s" file.any | xxd -
Masalah dengan penggunaan
stat
adalah bahwa itu adalah ekstensi GNU (Linux).du -k
dancut -f1
ditentukan oleh POSIX dan karenanya portabel untuk sistem Unix apa pun.Solaris, misalnya, kapal dengan pesta tapi tidak dengan
stat
. Jadi ini tidak sepenuhnya hipotetis.ls
memiliki masalah yang sama dalam format output yang tepat tidak ditentukan, sehingga penguraian output tidak dapat dilakukan dengan mudah.du -h
juga merupakan ekstensi GNU.Tetap gunakan konstruksi portabel jika memungkinkan, dan Anda akan membuat hidup seseorang lebih mudah di masa depan. Mungkin milikmu sendiri.
sumber
du
tidak memberikan ukuran file, itu memberikan indikasi berapa banyak ruang file menggunakan, yang agak berbeda (biasanya ukuran yang dilaporkan olehdu
adalah ukuran file dibulatkan ke jumlah blok terdekat, di mana sebuah blok biasanya 512B atau 1kB atau 4kB).--bytes
atau-b
alih-alih-k
, harus menjadi jawaban yang diterima.-h
("manusia") daridu
akan menghasilkan jawaban yang paling tepat untuk kasus umum:,file_size=`du -h "$filename" | cut -f1
karena akan menampilkan K (kilobyte), M (Megabytes) atau G (Gigabytes) yang sesuai.-h
adalah ekstensi GNU; itu tidak standarAnda juga dapat menggunakan perintah "jumlah kata" (
wc
):Masalahnya
wc
adalah ia akan menambahkan nama file dan membuat indentasi hasilnya. Sebagai contoh:Jika Anda ingin menghindari chaining bahasa yang ditafsirkan penuh atau editor aliran hanya untuk mendapatkan jumlah ukuran file, cukup arahkan kembali input dari file sehingga
wc
tidak pernah melihat nama file:Formulir terakhir ini dapat digunakan dengan substitusi perintah untuk dengan mudah mengambil nilai yang Anda cari sebagai variabel shell, seperti yang disebutkan oleh Gilles di bawah ini.
sumber
wc -c <"$FILENAME"
memberikan ukuran tanpa cruft lainnya, dengan demikiansize=$(wc -c <"$FILENAME")
.wc -c < file
tampaknya sangat cepat, setidaknya pada OS X. Saya menduga bahwa wc memiliki otak untuk mencoba membuat stat file jika hanya -c yang ditentukan.wc -c
menggunakanfstat
, tetapi kemudian mencari blok kedua-terakhir dari file dan membacast_blksize
byte terakhir yang up-to . Rupanya ini karena file di Linux/proc
dan/sys
misalnya memiliki ukuran stat yang hanya perkiraan , danwc
ingin melaporkan ukuran sebenarnya, bukan ukuran yang dilaporkan stat. Saya kira itu akan aneh untukwc -c
melaporkan ukuran yang berbeda dariwc
, tetapi itu bukan ide untuk membaca data dari file jika itu adalah file disk yang normal, dan itu tidak ada dalam memori. Atau lebih buruk, penyimpanan tape dekat-line ...printf
masih melihat lekukan, misalnyaprintf "Size: $size"
->size: <4 spaces> 54339
. Di sisi lainecho
mengabaikan spasi. Adakah cara untuk membuatnya konsisten?fstat
. Coba jalankanstrace wc -c </etc/passwd
dan Anda dapat melihat apa yang dilakukannya.BSD (Mac OS X)
stat
memiliki flag argumen format yang berbeda, dan penentu lapangan yang berbeda. Dariman stat(1)
:-f format
: Menampilkan informasi menggunakan format yang ditentukan. Lihat bagian FORMAT untuk deskripsi format yang valid.z
: Ukuran file dalam byte.Jadi semuanya sekarang:
sumber
Tergantung apa yang Anda maksud dengan ukuran .
akan memberi Anda jumlah byte yang dapat dibaca dari file. TKI, itu ukuran isi file. Namun ia akan membaca isi file (kecuali jika file tersebut adalah file biasa atau symlink ke file biasa di sebagian besar
wc
implementasi sebagai optimasi). Itu mungkin memiliki efek samping. Misalnya, untuk pipa bernama, apa yang telah dibaca tidak dapat lagi dibaca lagi dan untuk hal-hal seperti/dev/zero
atau/dev/random
yang berukuran tak terbatas, itu akan memakan waktu cukup lama. Itu juga berarti Anda memerlukanread
izin untuk file tersebut, dan cap waktu akses terakhir dari file tersebut dapat diperbarui.Itu standar dan portabel, namun perlu dicatat bahwa beberapa
wc
implementasi mungkin termasuk memimpin kosong dalam output itu. Salah satu cara untuk menghilangkannya adalah dengan menggunakan:atau untuk menghindari kesalahan tentang ekspresi aritmatika kosong di
dash
atauyash
saatwc
tidak menghasilkan keluaran (seperti saat file tidak dapat dibuka):ksh93
memilikiwc
builtin (asalkan Anda mengaktifkannya, Anda juga dapat memanggilnya sebagaicommand /opt/ast/bin/wc
) yang membuatnya paling efisien untuk file biasa di shell itu.Berbagai sistem memiliki perintah yang disebut
stat
antarmuka untuk panggilan sistemstat()
ataulstat()
.Informasi laporan tersebut ditemukan dalam inode. Salah satu informasi itu adalah
st_size
atribut. Untuk file biasa, itu ukuran konten (seberapa banyak data dapat dibaca dari itu tanpa adanya kesalahan (itulah yang sebagian besarwc -c
implementasi digunakan dalam optimasi mereka)). Untuk symlink, itu ukuran dalam byte dari jalur target. Untuk pipa bernama, tergantung pada sistem, itu 0 atau jumlah byte saat ini di buffer pipa. Sama untuk perangkat blok di mana tergantung pada sistem, Anda mendapatkan 0 atau ukuran dalam byte penyimpanan yang mendasarinya.Anda tidak perlu izin baca ke file untuk mendapatkan informasi itu, hanya izin pencarian ke direktori yang ditautkan.
Dengan urutan kronologis, ada:
IRIX
stat
(90-an):mengembalikan
st_size
atribut$file
(lstat()
) atau:sama kecuali kapan
$file
symlink dalam hal ini adalahst_size
file setelah resolusi symlink.zsh
stat
builtin (sekarang juga dikenal sebagaizstat
) dalamzsh/stat
modul (dimuat denganzmodload zsh/stat
) (1997):atau untuk menyimpan dalam variabel:
jelas, itu yang paling efisien di shell itu.
GNU
stat
(2001); juga di BusyBoxstat
sejak 2005 (disalin dari GNUstat
):(perhatikan arti
-L
terbalik dibandingkan dengan IRIX atauzsh
stat
.BSD
stat
(2002):Atau Anda dapat menggunakan
stat()
/lstat()
fungsi beberapa bahasa scripting sepertiperl
:AIX juga memiliki
istat
perintah yang akan membuang semua informasistat()
(tidaklstat()
, jadi tidak akan bekerja pada symlinks) dan yang dapat Anda posting setelahnya, misalnya:(terima kasih @JeffSchaller untuk bantuan mencari tahu detailnya ).
Di
tcsh
:(ukuran setelah resolusi symlink)
Jauh sebelum GNU memperkenalkan
stat
perintahnya, hal yang sama dapat dicapai denganfind
perintah GNU dengan-printf
predikatnya (sudah pada tahun 1991):Namun satu masalah adalah itu tidak berfungsi jika
$file
dimulai dengan-
atau merupakanfind
predikat (seperti!
,(
...).Perintah standar untuk mendapatkan
stat()
/lstat()
informasi adalahls
.POSIXly, Anda dapat melakukan:
dan tambahkan
-L
untuk resolusi symlink yang sama setelah. Itu tidak berfungsi untuk file perangkat meskipun di mana bidang ke- 5 adalah nomor utama perangkat, bukan ukurannya.Untuk perangkat blok, sistem tempat
stat()
pengembalian 0 untukst_size
, biasanya memiliki API lain untuk melaporkan ukuran perangkat blok. Sebagai contoh, Linux memilikiBLKGETSIZE64
ioctl()
, dan sebagian besar distribusi Linux sekarang dikirimkan denganblockdev
perintah yang dapat memanfaatkannya:Namun, Anda perlu izin baca ke file perangkat untuk itu. Biasanya dimungkinkan untuk mendapatkan ukuran dengan cara lain. Misalnya (masih di Linux):
Seharusnya berfungsi kecuali untuk perangkat kosong.
Pendekatan yang berfungsi untuk semua file yang dapat dicari (termasuk file biasa, sebagian besar perangkat blok dan beberapa perangkat karakter) adalah membuka file dan mencari sampai akhir:
Dengan
zsh
(setelah memuatzsh/system
modul):Dengan
ksh93
:atau
dengan
perl
:Untuk pipa bernama, kita telah melihat bahwa beberapa sistem (AIX, Solaris, HP / UX setidaknya) membuat jumlah data dalam buffer pipa yang tersedia di
stat()
'sst_size
. Beberapa (seperti Linux atau FreeBSD) tidak.Di Linux setidaknya, Anda dapat menggunakan
FIONREAD
ioctl()
setelah membuka pipa (dalam mode baca + tulis untuk menghindari menggantung):Namun perhatikan bahwa sementara itu tidak membaca konten pipa, pembukaan pipa yang dinamai di sini masih dapat memiliki efek samping. Kami menggunakan
fuser
untuk memeriksa terlebih dahulu bahwa beberapa proses sudah memiliki pipa terbuka untuk meringankan itu tetapi itu tidak mudah karenafuser
mungkin tidak dapat memeriksa semua proses.Sekarang, sejauh ini kami hanya mempertimbangkan ukuran data primer yang terkait dengan file. Itu tidak memperhitungkan ukuran metadata dan semua infrastruktur pendukung yang diperlukan untuk menyimpan file itu.
Atribut inode lain yang dikembalikan oleh
stat()
adalahst_blocks
. Itu adalah jumlah blok 512 byte yang digunakan untuk menyimpan data file (dan terkadang beberapa metadata-nya seperti atribut yang diperluas pada sistem file ext4 di Linux). Itu tidak termasuk inode itu sendiri, atau entri dalam direktori file yang ditautkan.Ukuran dan penggunaan disk tidak selalu terkait erat seperti kompresi, sparseness (kadang-kadang beberapa metadata), infrastruktur tambahan seperti blok tidak langsung di beberapa sistem file memiliki pengaruh pada yang terakhir.
Itulah yang biasanya
du
digunakan untuk melaporkan penggunaan disk. Sebagian besar perintah yang tercantum di atas akan dapat memberi Anda informasi itu.POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'
POSIXLY_CORRECT=1 du -s -- "$file"
(bukan untuk direktori di mana itu termasuk penggunaan disk dari file-file di dalamnya).find -- "$file" -printf '%b\n'
zstat -L +block -- $file
stat -c %b -- "$file"
stat -f %b -- "$file"
perl -le 'print((lstat shift)[12])' -- "$file"
sumber
wc -c
digunakanfstat
, tetapi kemudian membacast_blksize
byte terakhir yang terakhir . Rupanya ini karena file di Linux/proc
dan/sys
misalnya memiliki ukuran stat yang hanya perkiraan . Ini bagus untuk kebenaran, tetapi buruk jika ujung file ada di disk dan tidak ada di memori (khususnya jika digunakan pada banyak file dalam satu lingkaran). Dan sangat buruk jika file dimigrasi ke penyimpanan tape dekat-line , atau misalnya sistem file FUSE transparan-dekompresi.ls -go file | awk '{print $3}'
-go
adalah yang SysV, mereka tidak akan bekerja pada BSD (opsional (XSI) di POSIX). Anda juga perluls -god file | awk '{print $3; exit}'
(-d
agar dapat bekerja pada direktori,exit
untuk symlink dengan baris baru di target). Masalah dengan file perangkat juga tetap ada.wc -c
yang melaporkan jumlah byte.Script ini menggabungkan banyak cara untuk menghitung ukuran file:
Skrip ini berfungsi pada banyak sistem Unix termasuk Linux, BSD, OSX, Solaris, SunOS, dll.
Ukuran file menunjukkan jumlah byte. Ini adalah ukuran yang jelas, yaitu byte yang digunakan file pada disk biasa, tanpa kompresi khusus, atau area jarang khusus, atau blok yang tidak terisi, dll.
Skrip ini memiliki versi produksi dengan bantuan lebih banyak dan lebih banyak opsi di sini: https://github.com/SixArm/file-size
sumber
stat tampaknya melakukan ini dengan panggilan sistem paling sedikit:
sumber
ls -l filename
akan memberi Anda banyak informasi tentang file, termasuk ukuran file, izin, dan pemiliknya.Ukuran file di kolom kelima, dan ditampilkan dalam byte. Dalam contoh di bawah ini, ukuran file hanya di bawah 2KB:
Sunting: Ini tampaknya tidak dapat diandalkan seperti
stat
perintah.sumber
ls -l
danstat
perintah memberikan informasi ukuran yang dapat diandalkan. Saya tidak menemukan referensi yang bertentangan.ls -s
akan memberikan ukuran dalam jumlah blok.du filename
akan memberi tahu Anda penggunaan disk dalam byte.Saya lebih suka
du -h filename
, yang memberi Anda ukuran dalam format yang dapat dibaca manusia.sumber
stat -c "%s"
;)du
mencetak ukuran dalam blok 1024 byte, bukan hitungan sederhana byte.du
memberikan output dalam jumlah unit 512-byte. GNUdu
menggunakan kibibytes sebagai gantinya kecuali dipanggil denganPOSIXLY_CORRECT
di lingkungannya.Buat fungsi utilitas kecil di skrip shell yang dapat Anda delegasikan.
Contoh
Berdasarkan info dari jawaban @ Stéphane Chazelas.
sumber
gzip -v < file > /dev/null
untuk memeriksa kompresibilitas file.case
pernyataan.case
adalah konstruk Bourne / POSIX untuk melakukan pencocokan pola.[[...]]
hanya ksh / bash / zsh (dengan variasi).Saya menemukan liner AWK 1, dan ada bug tetapi saya memperbaikinya. Saya juga menambahkan PetaBytes setelah TeraBytes.
Mengingat stat tidak ada di setiap sistem, Anda hampir selalu dapat menggunakan solusi AWK. Contoh; Raspberry Pi tidak memiliki stat tetapi memiliki awk .
sumber
Satu cara lain yang sesuai dengan POSIX adalah menggunakan
awk
denganlength()
fungsinya yang mengembalikan panjang, dalam karakter pada setiap baris dari file input, tidak termasuk karakter baris baru. Jadi dengan melakukankami memastikan
NR
ditambahkan kesum
, sehingga menghasilkan jumlah total karakter dan jumlah baris baru yang ditemui dalam file. Thelength()
fungsi dalamawk
mengambil sebuah argumen yang dengan cara standarlength($0)
yang untuk seluruh baris saat ini.sumber
printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'
harus mencetak 3 tetapi mencetak 4.Saya suka opsi wc sendiri. Dipasangkan dengan 'bc,' Anda bisa mendapatkan desimal ke tempat sebanyak yang Anda mau.
Saya sedang mencari cara untuk memperbaiki skrip yang telah saya buat di kolom 'ukuran file' dari perintah 'ls -alh'. Saya tidak ingin hanya ukuran file integer, dan dua desimal sepertinya cocok, jadi setelah membaca diskusi ini, saya datang dengan kode di bawah ini.
Saya sarankan melanggar garis di titik koma jika Anda memasukkan ini dalam naskah.
file=$1; string=$(wc -c $file); bite=${string% *}; okay=$(echo "scale=2; $bite/1024" | bc);friend=$(echo -e "$file $okay" "kb"); echo -e "$friend"
Script saya disebut gpfl , untuk "dapatkan panjang file gambar." Saya menggunakannya setelah melakukan mogrify pada file di imagemagick, sebelum membuka atau memuat ulang gambar di GUI jpeg viewer.
Saya tidak tahu bagaimana ini menilai sebagai "jawaban," karena meminjam banyak dari apa yang sudah ditawarkan dan dibahas. Jadi saya akan meninggalkannya di sana.
BZT
sumber
wc
tidak membaca blok terakhir dari file, seandainyastat.st_size
hanya perkiraan (seperti untuk Linux/proc
dan/sys
file). Saya kira mereka memutuskan untuk tidak membuat komentar utama lebih rumit ketika mereka menambahkan logika itu beberapa baris ke bawah: lingrok.org/xref/coreutils/src/wc.c# 246Metode tercepat dan paling sederhana (IMO) adalah:
sumber
du
danwc
jawaban yang harus memiliki penafian TIDAK PERNAH MELAKUKANNYA dalam kehidupan nyata. Saya hanya menggunakan jawaban saya dalam aplikasi kehidupan nyata malam ini dan berpikir itu layak untuk dibagikan. Saya kira kita semua memiliki pendapat kami mengangkat bahu .