@ haunted85 states la forma más sencilla, suponiendo que esté utilizando Linux o Cygwin ( statno es estándar). wc -csegún lo sugerido por Eugéne es portátil.
Gilles
2
stat: illegal option -- c
Iulian Onofrei
stat --printf="%s" file.txtno muestra nada en Debian Jessie ...
woohoo
55
En MacOS esto funciona:stat -f%z myfile.tar
ccpizza
2
@woohoo Su solicitud sobrescribe la salida. man statdice que --printf omite la nueva línea final. Use --formato -cpara ver la salida. Obtenga más información al comparar stat --printf="%s" file.any | xxd -constat -c "%s" file.any | xxd -
nieto
92
file_size_kb=`du -k "$filename" | cut -f1`
El problema con el uso states que es una extensión GNU (Linux). du -ky cut -f1están especificados por POSIX y, por lo tanto, son portátiles para cualquier sistema Unix.
Solaris, por ejemplo, se envía con bash pero no con stat. Entonces esto no es del todo hipotético.
lstiene un problema similar en que no se especifica el formato exacto de la salida, por lo que el análisis de su salida no se puede hacer de forma portátil. du -hTambién es una extensión GNU.
Apéguese a construcciones portátiles siempre que sea posible, y facilitará la vida de alguien en el futuro. Quizás el tuyo.
duno da el tamaño del archivo, da una indicación de cuánto espacio usa el archivo, que es sutilmente diferente (por lo general, el tamaño reportado dues el tamaño del archivo redondeado al número más cercano de bloques, donde un bloque es típicamente 512B o 1kB o 4kB).
Gilles
77
@Gilles, los archivos dispersos (es decir, los que tienen agujeros) reportan menos de la longitud.
vonbrand
55
Esta, con --byteso en -blugar de -k, debería ser la respuesta aceptada.
Amedee Van Gasse
1
La -hopción ("humano")du producirá la respuesta más apropiada para casos generales: file_size=`du -h "$filename" | cut -f1ya que mostrará K (kilobytes), M (Megabytes) o G (Gigabytes) según corresponda.
Fralau 01 de
1
@fralau: El OP quiere "asignar esto a una variable bash para que puedan usarlo más tarde", por lo que es mucho más probable que quieran un valor numérico real, no una aproximación legible por humanos. Además, -hes una extensión GNU; no es estándar
Nemo
74
También puede usar el comando "Word Count" ( wc):
wc -c "$filename"| awk '{print $1}'
El problema con wces que agregará el nombre del archivo y sangrará la salida. Por ejemplo:
$ wc -c somefile.txt
1160 somefile.txt
Si desea evitar encadenar un lenguaje interpretado completo o un editor de secuencias solo para obtener un recuento de tamaño de archivo, simplemente redirija la entrada del archivo para que wcnunca vea el nombre de archivo:
wc -c <"$filename"
Esta última forma se puede usar con la sustitución de comandos para obtener fácilmente el valor que estaba buscando como una variable de shell, como lo menciona Gilles a continuación.
wc -c <"$FILENAME"da el tamaño sin otra migaja, por lo tanto size=$(wc -c <"$FILENAME").
Gilles
66
Solo un punto más: acabo de probarlo y wc -c < fileparece ser muy rápido, al menos en OS X. Supongo que wc tiene el cerebro para tratar de registrar el archivo si solo se especifica -c.
Edward Falk
44
@EdwardFalk: GNU wc -cusa fstat, pero luego busca el penúltimo bloque del archivo y lee los últimos st_blksizebytes hasta . Aparentemente, esto se debe a que los archivos en Linux /procy, /syspor ejemplo, tienen tamaños de estadísticas que son solo aproximados y wcquieren informar el tamaño real, no el tamaño de estadísticas. Supongo que sería extraño wc -cinformar un tamaño diferente wc, pero no es idea leer datos del archivo si es un archivo de disco normal y no está en la memoria. O peor, almacenamiento de cinta casi en línea ...
Peter Cordes
1
Parece que printftodavía ve la sangría, por ejemplo, printf "Size: $size"-> size: <4 spaces> 54339. Por otro lado echoignora los espacios en blanco. ¿Alguna forma de hacerlo consistente?
Eugene Kulabuhov
2
@keithpjolley: llamando fstat. Intenta correr strace wc -c </etc/passwdy podrás ver lo que está haciendo.
Nemo
48
Los BSD (Mac OS X) stattienen un indicador de argumento de formato diferente y diferentes especificadores de campo. De man stat(1):
-f format: Muestra información utilizando el formato especificado. Consulte la sección FORMATOS para obtener una descripción de los formatos válidos.
le dará la cantidad de bytes que se pueden leer del archivo. IOW, es el tamaño del contenido del archivo. Sin embargo, leerá el contenido del archivo (excepto si el archivo es un archivo normal o un enlace simbólico a un archivo normal en la mayoría de las wcimplementaciones como una optimización). Eso puede tener efectos secundarios. Por ejemplo, para una tubería con nombre, lo que se ha leído ya no se puede leer nuevamente y para cosas como /dev/zeroo /dev/randomque son de tamaño infinito, llevará un tiempo. Eso también significa que necesita readpermiso para el archivo, y la última marca de tiempo de acceso del archivo puede actualizarse.
Eso es estándar y portátil, sin embargo, tenga en cuenta que algunas wcimplementaciones pueden incluir espacios en blanco iniciales en esa salida. Una forma de deshacerse de ellos es usar:
size=$(($(wc -c <"$file")))
o para evitar un error sobre una expresión aritmética vacía en dasho yashcuando wcno produce salida (como cuando el archivo no se puede abrir):
size=$(($(wc -c <"$file")+0))
ksh93tiene wcincorporado (siempre que lo habilite, también puede invocarlo como command /opt/ast/bin/wc) lo que lo convierte en el más eficiente para los archivos normales en ese shell.
Varios sistemas tienen un comando llamado statque es una interfaz para los stat()o lstat()llamadas al sistema.
Esos reportan información encontrada en el inodo. Una de esa información es el st_sizeatributo. Para los archivos normales, ese es el tamaño del contenido (cuántos datos podrían leerse en ausencia de error (eso es lo que la mayoría de las wc -cimplementaciones usan en su optimización)). Para enlaces simbólicos, ese es el tamaño en bytes de la ruta de destino. Para canalizaciones con nombre, según el sistema, es 0 o el número de bytes actualmente en el búfer de canalización. Lo mismo para dispositivos de bloque donde, dependiendo del sistema, obtienes 0 o el tamaño en bytes del almacenamiento subyacente.
No necesita permiso de lectura en el archivo para obtener esa información, solo busque permiso para el directorio al que está vinculado.
stat -f %z --"$file"# st_size of file
stat -Lf%z --"$file"# after symlink resolution
O puede usar la función stat()/ lstat()de algún lenguaje de script como perl:
perl -le 'print((lstat shift)[7])'--"$file"
AIX también tiene un istatcomando que volcará toda la información stat()(no lstat(), así que no funcionará en enlaces simbólicos) y con la que podría procesar posteriormente, por ejemplo:
(tamaño después de la resolución del enlace simbólico)
Mucho antes de que GNU introdujera su statcomando, lo mismo podría lograrse con el findcomando GNU con su -printfpredicado (ya en 1991):
find --"$file"-prune -printf '%s\n'# st_size of file
find -L --"$file"-prune -printf '%s\n'# after symlink resolution
Sin embargo, un problema es que no funciona si $filecomienza con -o es un findpredicado (como !, (...).
El comando estándar para obtener la información stat()/ lstat()es ls.
POSIXY, puedes hacer:
LC_ALL=C ls -dn --"$file"| awk '{print $5; exit}'
y agregue -Llo mismo después de la resolución del enlace simbólico. Eso no funciona para los archivos de dispositivos, aunque en la 5 ª campo es el dispositivo de mayor número en lugar del tamaño.
Para los dispositivos de bloque, los sistemas donde stat()devuelve 0 st_size, generalmente tienen otras API para informar el tamaño del dispositivo de bloque. Por ejemplo, Linux tiene BLKGETSIZE64ioctl(), y la mayoría de las distribuciones de Linux ahora se envían con un blockdevcomando que puede usarlo:
blockdev --getsize64 --"$device_file"
Sin embargo, necesita permiso de lectura en el archivo del dispositivo para eso. Por lo general, es posible derivar el tamaño por otros medios. Por ejemplo (todavía en Linux):
lsblk -bdno size --"$device_file"
Debería funcionar excepto para dispositivos vacíos.
Un enfoque que funciona para todos los archivos buscables (por lo que incluye archivos normales, la mayoría de los dispositivos de bloque y algunos dispositivos de caracteres) es abrir el archivo y buscar hasta el final:
Con zsh(después de cargar el zsh/systemmódulo):
{sysseek -w end 0&& size=$((systell(0)))}< $file
Con ksh93:
<"$file"<#((size=EOF))
o
{ size=$(<#((EOF)));}<"$file"
con perl:
perl -le 'seek STDIN, 0, 2 or die "seek: $!"; print tell STDIN'<"$file"
Para las tuberías con nombre, hemos visto que algunos sistemas (AIX, Solaris, HP / UX al menos) hacen que la cantidad de datos en el búfer de tuberías esté disponible en stat()'s st_size. Algunos (como Linux o FreeBSD) no lo hacen.
Al menos en Linux, puede usar FIONREADioctl()después de haber abierto la tubería (en modo lectura + escritura para evitar que se cuelgue):
Sin embargo, tenga en cuenta que si bien no lee el contenido de la tubería, la simple apertura de la tubería con nombre aquí todavía puede tener efectos secundarios. Estamos usando fuserpara verificar primero que algún proceso ya tiene la tubería abierta para aliviar eso, pero eso no es infalible ya que es fuserposible que no pueda verificar todos los procesos.
Ahora, hasta ahora solo hemos estado considerando el tamaño de los datos primarios asociados con los archivos. Eso no tiene en cuenta el tamaño de los metadatos y toda la infraestructura de soporte necesaria para almacenar ese archivo.
Otro atributo de inodo devuelto por stat()es st_blocks. Esa es la cantidad de bloques de 512 bytes que se utilizan para almacenar los datos del archivo (y, a veces, algunos de sus metadatos, como los atributos extendidos en los sistemas de archivos ext4 en Linux). Eso no incluye el inodo en sí, o las entradas en los directorios a los que está vinculado el archivo.
El tamaño y el uso del disco no están necesariamente estrechamente relacionados como la compresión, la escasez (a veces algunos metadatos), la infraestructura adicional como los bloques indirectos en algunos sistemas de archivos influyen en estos últimos.
Eso suele ser lo que se duusa para informar el uso del disco. La mayoría de los comandos enumerados anteriormente podrán obtener esa información.
POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'
POSIXLY_CORRECT=1 du -s -- "$file" (no para directorios donde eso incluiría el uso del disco de los archivos dentro).
claramente la respuesta más completa e informativa. gracias. puedo usar esto para crear scripts de bash multiplataforma usando la información de estadísticas BSD y GNU
¿No funcionaría esto tambiénls -go file | awk '{print $3}'
Steven Penny
@StevenPenny esos -goserían los SysV , no funcionarían en BSD (opcional (XSI) en POSIX). También necesitaría ls -god file | awk '{print $3; exit}'( -dpara que funcione en directorios, exitpara enlaces simbólicos con nuevas líneas en el destino). Los problemas con los archivos del dispositivo también permanecen.
Stéphane Chazelas
1
@ αғsнιη la API de Unix no hace distinción entre archivos de texto y binarios. Son todas las secuencias de bytes. Algunas aplicaciones pueden querer interpretar esos bytes como texto, pero obviamente no lo wc -cque informa el número de bytes.
Stéphane Chazelas
22
Este script combina muchas formas de calcular el tamaño del archivo:
El script funciona en muchos sistemas Unix, incluidos Linux, BSD, OSX, Solaris, SunOS, etc.
El tamaño del archivo muestra el número de bytes. Es el tamaño aparente, que son los bytes que utiliza el archivo en un disco típico, sin compresión especial, o áreas dispersas especiales, o bloques no asignados, etc.
Creo que ambos ls -ly el statcomando dan información confiable sobre el tamaño. No encontré ninguna referencia a lo contrario. ls -sdará tamaño en número de bloques.
dabest1
2
@ dabest1 no es confiable en el sentido de que en otro Unix, su salida puede ser diferente (y en algunos Unix lo es).
Eugene Bujak
Sí, IIRC, Solaris no mostraba el nombre del grupo de forma predeterminada, lo que generaba menos columnas en la salida.
Edward Falk
Dado que el tamaño es numérico puro, rodeado de espacios en blanco, y el año de la fecha es numérico puro, en un formato definido, sería posible utilizar una expresión regular para tratar usuario + propietario como un campo, independientemente de si el grupo estaba presente o no. (¡un ejercicio para el lector!)
MikeW
5
du filename le dirá el uso del disco en bytes.
Prefiero du -h filename, que te da el tamaño en un formato legible para humanos.
Este sabor de duimprime el tamaño en bloques de 1024 bytes, no un simple recuento de bytes.
Peter Lyons
Tenga en cuenta que el estándar duproporciona una salida en número de unidades de 512 bytes. GNU duusa kibibytes a menos que se llame con POSIXLY_CORRECTen su entorno.
Stéphane Chazelas
1
Para archivos de tipo directorio , eso proporciona el uso del disco del directorio, pero también de todos los demás archivos dentro (recursivamente).
Stéphane Chazelas
3
Cree pequeñas funciones de utilidad en sus scripts de shell en las que pueda delegar.
Ejemplo
#! /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
Basado en información de la respuesta de @ Stéphane Chazelas.
Consulte también gzip -v < file > /dev/nullpara verificar la compresibilidad de un archivo.
Stéphane Chazelas
@ StéphaneChazelas no estoy seguro si creo que fue una mejora. esas declaraciones de casos pueden posponer fácilmente los noobs; Ciertamente, nunca recuerdo cómo hacerlo correctamente :-) ¿son las declaraciones de casos inherentemente más portátiles desde que lo hiciste? veo el punto cuando hay más de dos casos, pero de lo contrario ... +
oligofren
1
Supongo que también es cuestión de gustos, pero aquí es el caso típico en el que querrías usar una casedeclaración. casees la construcción Bourne / POSIX para hacer coincidencia de patrones. [[...]]es solo ksh / bash / zsh (con variaciones).
Stéphane Chazelas
2
Encontré un forro AWK 1, y tenía un error, pero lo arreglé. También agregué en PetaBytes después de TeraBytes.
Teniendo en cuenta que stat no está en todos los sistemas, casi siempre puede usar la solución AWK. Ejemplo; la Raspberry Pi no tiene estadísticas, pero sí tiene awk .
Completamente NO lo que pidió el OP, pero es un buen trabajo.
Gypsy Spellweaver
0
Otra forma compatible con POSIX sería usar awkcon su length()función que devuelve la longitud, en caracteres en cada línea del archivo de entrada, excluyendo los caracteres de nueva línea. Entonces haciendo
awk '{ sum+=length } END { print sum+NR }' file
nos aseguramos de que NRse agregue sum, lo que da como resultado el recuento total de caracteres y el número total de nuevas líneas encontradas en el archivo. La length()función en awktoma un argumento que por defecto significa length($0)que es para la línea completa actual.
No si la última línea no termina en una nueva línea: printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'debería imprimir 3 pero imprime 4.
Isaac
-1
Me gusta la opción wc yo mismo. Junto con 'bc', puede obtener decimales en tantos lugares como desee.
Estaba buscando mejorar un script que tenía que despertaba la columna 'tamaño de archivo' de un comando 'ls -alh'. No quería solo los tamaños de archivos enteros, y dos decimales parecían adaptarse, así que después de leer esta discusión, se me ocurrió el código a continuación.
Sugiero romper la línea en punto y coma si incluye esto en un script.
Mi script se llama gpfl , para "obtener la longitud del archivo de imagen". Lo uso después de hacer un mogrify en un archivo en imagemagick, antes de abrir o volver a cargar una imagen en un visor jpeg GUI.
No sé cómo esto califica como una "respuesta", ya que toma mucho prestado de lo que ya se ha ofrecido y discutido. Entonces lo dejaré allí.
Preferiría usar "stat" o "ls". Por lo general, no me gusta usar "wc" para obtener tamaños de archivo porque lee físicamente todo el archivo. Si tiene muchos archivos, o archivos particularmente grandes, esto puede llevar mucho tiempo. Pero tu solución es creativa ... + 1.
Kevin Fegan
2
Estoy de acuerdo con la idea de usar "stat" sobre "wc" para el tamaño del archivo, sin embargo, si usa "wc -c", no se leerán datos; en su lugar, lseek se usará para calcular la cantidad de bytes en un archivo. lingrok.org/xref/coreutils/src/wc.c#228
bbaja42
1
@ bbaja42: tenga en cuenta que GNU Coreutils wclee el último bloque del archivo, en caso de que stat.st_sizefuera solo una aproximación (como para Linux /procy /sysarchivos). Supongo que decidieron no hacer el comentario principal más complicado cuando agregaron esa lógica un par de líneas: lingrok.org/xref/coreutils/src/wc.c#246
Luego vota una o más de las respuestas existentes que mencionan stat; no es necesario repetirlo de nuevo ...
Jeff Schaller
1
@JeffSchaller Acabo de votar la respuesta de Stephane sobre tus instrucciones. Creo que es demasiado complicado para mis propósitos. Es por eso que publiqué esta respuesta simple para almas afines.
WinEunuuchs2Unix
1
Gracias; es solo que una sexta instancia de una respuesta "estadística" no simplifica estas preguntas y respuestas, sino que prefiere que un nuevo lector se pregunte "¿en qué se diferencia esta respuesta de las otras?" y conducir a más confusión en lugar de menos.
Jeff Schaller
@JeffSchaller, supongo. Pero podría quejarme de las muchas duy wcrespuestas que deberían tener un descargo de responsabilidad NUNCA HAGA ESTO en la vida real. Esta noche utilicé mi respuesta en una aplicación de la vida real y pensé que valía la pena compartirla. Supongo que todos tenemos nuestras opiniones encogidas de hombros .
pv
ycat
para un comando de copia que muestre progreso y ETA :)Respuestas:
Su mejor apuesta si está en un sistema GNU:
De man stat :
En un script bash:
NOTA: vea la respuesta de @ chbrown para saber cómo usar stat en la terminal en Mac OS X.
fuente
stat
es la forma más sencilla, suponiendo que esté utilizando Linux o Cygwin (stat
no es estándar).wc -c
según lo sugerido por Eugéne es portátil.stat: illegal option -- c
stat --printf="%s" file.txt
no muestra nada en Debian Jessie ...stat -f%z myfile.tar
man stat
dice que --printf omite la nueva línea final. Use--format
o-c
para ver la salida. Obtenga más información al compararstat --printf="%s" file.any | xxd -
constat -c "%s" file.any | xxd -
El problema con el uso
stat
es que es una extensión GNU (Linux).du -k
ycut -f1
están especificados por POSIX y, por lo tanto, son portátiles para cualquier sistema Unix.Solaris, por ejemplo, se envía con bash pero no con
stat
. Entonces esto no es del todo hipotético.ls
tiene un problema similar en que no se especifica el formato exacto de la salida, por lo que el análisis de su salida no se puede hacer de forma portátil.du -h
También es una extensión GNU.Apéguese a construcciones portátiles siempre que sea posible, y facilitará la vida de alguien en el futuro. Quizás el tuyo.
fuente
du
no da el tamaño del archivo, da una indicación de cuánto espacio usa el archivo, que es sutilmente diferente (por lo general, el tamaño reportadodu
es el tamaño del archivo redondeado al número más cercano de bloques, donde un bloque es típicamente 512B o 1kB o 4kB).--bytes
o en-b
lugar de-k
, debería ser la respuesta aceptada.-h
opción ("humano")du
producirá la respuesta más apropiada para casos generales:file_size=`du -h "$filename" | cut -f1
ya que mostrará K (kilobytes), M (Megabytes) o G (Gigabytes) según corresponda.-h
es una extensión GNU; no es estándarTambién puede usar el comando "Word Count" (
wc
):El problema con
wc
es que agregará el nombre del archivo y sangrará la salida. Por ejemplo:Si desea evitar encadenar un lenguaje interpretado completo o un editor de secuencias solo para obtener un recuento de tamaño de archivo, simplemente redirija la entrada del archivo para que
wc
nunca vea el nombre de archivo:Esta última forma se puede usar con la sustitución de comandos para obtener fácilmente el valor que estaba buscando como una variable de shell, como lo menciona Gilles a continuación.
fuente
wc -c <"$FILENAME"
da el tamaño sin otra migaja, por lo tantosize=$(wc -c <"$FILENAME")
.wc -c < file
parece ser muy rápido, al menos en OS X. Supongo que wc tiene el cerebro para tratar de registrar el archivo si solo se especifica -c.wc -c
usafstat
, pero luego busca el penúltimo bloque del archivo y lee los últimosst_blksize
bytes hasta . Aparentemente, esto se debe a que los archivos en Linux/proc
y,/sys
por ejemplo, tienen tamaños de estadísticas que son solo aproximados ywc
quieren informar el tamaño real, no el tamaño de estadísticas. Supongo que sería extrañowc -c
informar un tamaño diferentewc
, pero no es idea leer datos del archivo si es un archivo de disco normal y no está en la memoria. O peor, almacenamiento de cinta casi en línea ...printf
todavía ve la sangría, por ejemplo,printf "Size: $size"
->size: <4 spaces> 54339
. Por otro ladoecho
ignora los espacios en blanco. ¿Alguna forma de hacerlo consistente?fstat
. Intenta correrstrace wc -c </etc/passwd
y podrás ver lo que está haciendo.Los BSD (Mac OS X)
stat
tienen un indicador de argumento de formato diferente y diferentes especificadores de campo. Deman stat(1)
:-f format
: Muestra información utilizando el formato especificado. Consulte la sección FORMATOS para obtener una descripción de los formatos válidos.z
: El tamaño del archivo en bytes.Así que todos juntos ahora:
fuente
Depende de lo que entiendas por tamaño .
le dará la cantidad de bytes que se pueden leer del archivo. IOW, es el tamaño del contenido del archivo. Sin embargo, leerá el contenido del archivo (excepto si el archivo es un archivo normal o un enlace simbólico a un archivo normal en la mayoría de las
wc
implementaciones como una optimización). Eso puede tener efectos secundarios. Por ejemplo, para una tubería con nombre, lo que se ha leído ya no se puede leer nuevamente y para cosas como/dev/zero
o/dev/random
que son de tamaño infinito, llevará un tiempo. Eso también significa que necesitaread
permiso para el archivo, y la última marca de tiempo de acceso del archivo puede actualizarse.Eso es estándar y portátil, sin embargo, tenga en cuenta que algunas
wc
implementaciones pueden incluir espacios en blanco iniciales en esa salida. Una forma de deshacerse de ellos es usar:o para evitar un error sobre una expresión aritmética vacía en
dash
oyash
cuandowc
no produce salida (como cuando el archivo no se puede abrir):ksh93
tienewc
incorporado (siempre que lo habilite, también puede invocarlo comocommand /opt/ast/bin/wc
) lo que lo convierte en el más eficiente para los archivos normales en ese shell.Varios sistemas tienen un comando llamado
stat
que es una interfaz para losstat()
olstat()
llamadas al sistema.Esos reportan información encontrada en el inodo. Una de esa información es el
st_size
atributo. Para los archivos normales, ese es el tamaño del contenido (cuántos datos podrían leerse en ausencia de error (eso es lo que la mayoría de laswc -c
implementaciones usan en su optimización)). Para enlaces simbólicos, ese es el tamaño en bytes de la ruta de destino. Para canalizaciones con nombre, según el sistema, es 0 o el número de bytes actualmente en el búfer de canalización. Lo mismo para dispositivos de bloque donde, dependiendo del sistema, obtienes 0 o el tamaño en bytes del almacenamiento subyacente.No necesita permiso de lectura en el archivo para obtener esa información, solo busque permiso para el directorio al que está vinculado.
Por orden cronológico, hay:
IRIX
stat
(años 90):devuelve el
st_size
atributo de$file
(lstat()
) o:igual excepto cuando
$file
es un enlace simbólico en cuyo caso es elst_size
del archivo después de la resolución del enlace simbólico.zsh
stat
incorporado (ahora también conocido comozstat
) en elzsh/stat
módulo (cargado conzmodload zsh/stat
) (1997):o para almacenar en una variable:
obviamente, ese es el más eficiente en ese shell.
GNU
stat
(2001); También en BusyBoxstat
desde 2005 (copiado de GNUstat
):(tenga en cuenta que el significado de
-L
se invierte en comparación con IRIX ozsh
stat
.BSD
stat
(2002):O puede usar la función
stat()
/lstat()
de algún lenguaje de script comoperl
:AIX también tiene un
istat
comando que volcará toda la informaciónstat()
(nolstat()
, así que no funcionará en enlaces simbólicos) y con la que podría procesar posteriormente, por ejemplo:(Gracias a @JeffSchaller por la ayuda para descubrir los detalles ).
En
tcsh
:(tamaño después de la resolución del enlace simbólico)
Mucho antes de que GNU introdujera su
stat
comando, lo mismo podría lograrse con elfind
comando GNU con su-printf
predicado (ya en 1991):Sin embargo, un problema es que no funciona si
$file
comienza con-
o es unfind
predicado (como!
,(
...).El comando estándar para obtener la información
stat()
/lstat()
esls
.POSIXY, puedes hacer:
y agregue
-L
lo mismo después de la resolución del enlace simbólico. Eso no funciona para los archivos de dispositivos, aunque en la 5 ª campo es el dispositivo de mayor número en lugar del tamaño.Para los dispositivos de bloque, los sistemas donde
stat()
devuelve 0st_size
, generalmente tienen otras API para informar el tamaño del dispositivo de bloque. Por ejemplo, Linux tieneBLKGETSIZE64
ioctl()
, y la mayoría de las distribuciones de Linux ahora se envían con unblockdev
comando que puede usarlo:Sin embargo, necesita permiso de lectura en el archivo del dispositivo para eso. Por lo general, es posible derivar el tamaño por otros medios. Por ejemplo (todavía en Linux):
Debería funcionar excepto para dispositivos vacíos.
Un enfoque que funciona para todos los archivos buscables (por lo que incluye archivos normales, la mayoría de los dispositivos de bloque y algunos dispositivos de caracteres) es abrir el archivo y buscar hasta el final:
Con
zsh
(después de cargar elzsh/system
módulo):Con
ksh93
:o
con
perl
:Para las tuberías con nombre, hemos visto que algunos sistemas (AIX, Solaris, HP / UX al menos) hacen que la cantidad de datos en el búfer de tuberías esté disponible en
stat()
'sst_size
. Algunos (como Linux o FreeBSD) no lo hacen.Al menos en Linux, puede usar
FIONREAD
ioctl()
después de haber abierto la tubería (en modo lectura + escritura para evitar que se cuelgue):Sin embargo, tenga en cuenta que si bien no lee el contenido de la tubería, la simple apertura de la tubería con nombre aquí todavía puede tener efectos secundarios. Estamos usando
fuser
para verificar primero que algún proceso ya tiene la tubería abierta para aliviar eso, pero eso no es infalible ya que esfuser
posible que no pueda verificar todos los procesos.Ahora, hasta ahora solo hemos estado considerando el tamaño de los datos primarios asociados con los archivos. Eso no tiene en cuenta el tamaño de los metadatos y toda la infraestructura de soporte necesaria para almacenar ese archivo.
Otro atributo de inodo devuelto por
stat()
esst_blocks
. Esa es la cantidad de bloques de 512 bytes que se utilizan para almacenar los datos del archivo (y, a veces, algunos de sus metadatos, como los atributos extendidos en los sistemas de archivos ext4 en Linux). Eso no incluye el inodo en sí, o las entradas en los directorios a los que está vinculado el archivo.El tamaño y el uso del disco no están necesariamente estrechamente relacionados como la compresión, la escasez (a veces algunos metadatos), la infraestructura adicional como los bloques indirectos en algunos sistemas de archivos influyen en estos últimos.
Eso suele ser lo que se
du
usa para informar el uso del disco. La mayoría de los comandos enumerados anteriormente podrán obtener esa información.POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'
POSIXLY_CORRECT=1 du -s -- "$file"
(no para directorios donde eso incluiría el uso del disco de los archivos dentro).find -- "$file" -printf '%b\n'
zstat -L +block -- $file
stat -c %b -- "$file"
stat -f %b -- "$file"
perl -le 'print((lstat shift)[12])' -- "$file"
fuente
wc -c
usafstat
, pero luego lee los últimosst_blksize
bytes. Aparentemente, esto se debe a que los archivos en Linux/proc
y,/sys
por ejemplo, tienen tamaños de estadísticas que son solo aproximados . Esto es bueno para la corrección, pero malo si el final del archivo está en el disco y no en la memoria (especialmente si se usa en muchos archivos en un bucle). Y muy malo si el archivo se migra a un almacenamiento de cinta cercano a la línea o, por ejemplo, a un sistema de archivos de descompresión transparente FUSE.ls -go file | awk '{print $3}'
-go
serían los SysV , no funcionarían en BSD (opcional (XSI) en POSIX). También necesitaríals -god file | awk '{print $3; exit}'
(-d
para que funcione en directorios,exit
para enlaces simbólicos con nuevas líneas en el destino). Los problemas con los archivos del dispositivo también permanecen.wc -c
que informa el número de bytes.Este script combina muchas formas de calcular el tamaño del archivo:
El script funciona en muchos sistemas Unix, incluidos Linux, BSD, OSX, Solaris, SunOS, etc.
El tamaño del archivo muestra el número de bytes. Es el tamaño aparente, que son los bytes que utiliza el archivo en un disco típico, sin compresión especial, o áreas dispersas especiales, o bloques no asignados, etc.
Este script tiene una versión de producción con más ayuda y más opciones aquí: https://github.com/SixArm/file-size
fuente
stat parece hacer esto con la menor cantidad de llamadas al sistema:
fuente
ls -l filename
le dará mucha información sobre un archivo, incluido su tamaño, permisos y propietario.El tamaño del archivo en la quinta columna, y se muestra en bytes. En el ejemplo a continuación, el tamaño del archivo es de menos de 2 KB:
Editar: aparentemente no es tan confiable como el
stat
comando.fuente
ls -l
y elstat
comando dan información confiable sobre el tamaño. No encontré ninguna referencia a lo contrario.ls -s
dará tamaño en número de bloques.du filename
le dirá el uso del disco en bytes.Prefiero
du -h filename
, que te da el tamaño en un formato legible para humanos.fuente
stat -c "%s"
;)du
imprime el tamaño en bloques de 1024 bytes, no un simple recuento de bytes.du
proporciona una salida en número de unidades de 512 bytes. GNUdu
usa kibibytes a menos que se llame conPOSIXLY_CORRECT
en su entorno.Cree pequeñas funciones de utilidad en sus scripts de shell en las que pueda delegar.
Ejemplo
Basado en información de la respuesta de @ Stéphane Chazelas.
fuente
gzip -v < file > /dev/null
para verificar la compresibilidad de un archivo.case
declaración.case
es la construcción Bourne / POSIX para hacer coincidencia de patrones.[[...]]
es solo ksh / bash / zsh (con variaciones).Encontré un forro AWK 1, y tenía un error, pero lo arreglé. También agregué en PetaBytes después de TeraBytes.
Teniendo en cuenta que stat no está en todos los sistemas, casi siempre puede usar la solución AWK. Ejemplo; la Raspberry Pi no tiene estadísticas, pero sí tiene awk .
fuente
Otra forma compatible con POSIX sería usar
awk
con sulength()
función que devuelve la longitud, en caracteres en cada línea del archivo de entrada, excluyendo los caracteres de nueva línea. Entonces haciendonos aseguramos de que
NR
se agreguesum
, lo que da como resultado el recuento total de caracteres y el número total de nuevas líneas encontradas en el archivo. Lalength()
función enawk
toma un argumento que por defecto significalength($0)
que es para la línea completa actual.fuente
printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'
debería imprimir 3 pero imprime 4.Me gusta la opción wc yo mismo. Junto con 'bc', puede obtener decimales en tantos lugares como desee.
Estaba buscando mejorar un script que tenía que despertaba la columna 'tamaño de archivo' de un comando 'ls -alh'. No quería solo los tamaños de archivos enteros, y dos decimales parecían adaptarse, así que después de leer esta discusión, se me ocurrió el código a continuación.
Sugiero romper la línea en punto y coma si incluye esto en un script.
file=$1; string=$(wc -c $file); bite=${string% *}; okay=$(echo "scale=2; $bite/1024" | bc);friend=$(echo -e "$file $okay" "kb"); echo -e "$friend"
Mi script se llama gpfl , para "obtener la longitud del archivo de imagen". Lo uso después de hacer un mogrify en un archivo en imagemagick, antes de abrir o volver a cargar una imagen en un visor jpeg GUI.
No sé cómo esto califica como una "respuesta", ya que toma mucho prestado de lo que ya se ha ofrecido y discutido. Entonces lo dejaré allí.
BZT
fuente
wc
lee el último bloque del archivo, en caso de questat.st_size
fuera solo una aproximación (como para Linux/proc
y/sys
archivos). Supongo que decidieron no hacer el comentario principal más complicado cuando agregaron esa lógica un par de líneas: lingrok.org/xref/coreutils/src/wc.c#246El método más rápido y simple (IMO) es:
fuente
du
ywc
respuestas que deberían tener un descargo de responsabilidad NUNCA HAGA ESTO en la vida real. Esta noche utilicé mi respuesta en una aplicación de la vida real y pensé que valía la pena compartirla. Supongo que todos tenemos nuestras opiniones encogidas de hombros .