En Linux, lo uso stat --format="%s" FILE
, pero Solaris al que tengo acceso no tiene comando stat. ¿Qué debo usar entonces?
Estoy escribiendo scripts Bash y realmente no puedo instalar ningún software nuevo en el sistema.
Ya he considerado usar:
perl -e '@x=stat(shift);print $x[7]' FILE
o incluso:
ls -nl FILE | awk '{print $5}'
Pero ninguno de estos parece sensato: ¿ejecutar Perl solo para obtener el tamaño del archivo? ¿O ejecutar 2 comandos para hacer lo mismo?
Respuestas:
wc -c < filename
(abreviatura de recuento de palabras,-c
imprime el recuento de bytes) es una solución POSIX portátil . Solo el formato de salida puede no ser uniforme en todas las plataformas, ya que algunos espacios pueden estar precedidos (como es el caso de Solaris).No omita la redirección de entrada. Cuando el archivo se pasa como argumento, el nombre del archivo se imprime después del recuento de bytes.
Me preocupaba que no funcionara con archivos binarios, pero funciona bien tanto en Linux como en Solaris. Puedes probarlo con
wc -c < /usr/bin/wc
. Además, las utilidades POSIX están garantizadas para manejar archivos binarios , a menos que se especifique lo contrario explícitamente.fuente
wc -c < file
si no desea que aparezca el nombre del archivo.wc
en una canalización deberead()
todo el flujo contar los bytes. Las solucionesls
/awk
(y similares) usan una llamada al sistema para obtener el tamaño, que debería ser tiempo lineal (versus O (tamaño))wc
haber sido muy lento la última vez que hice eso en un disco duro lleno. Fue lo suficientemente lento como para poder volver a escribir el guión antes de que terminara el primero, vine aquí para recordar cómo lo hice jajaja.wc -c
; se ve mucho más ordenado perols
+awk
es mejor para la velocidad / uso de recursos. Además, solo quería señalar que en realidad también necesita postprocesar los resultadoswc
porque en algunos sistemas tendrá espacios en blanco antes del resultado, que es posible que deba eliminar antes de poder hacer comparaciones.wc -c
es genial, pero no funcionará si no tiene acceso de lectura al archivo.Terminé escribiendo mi propio programa (realmente pequeño) para mostrar solo el tamaño. Más información aquí: http://fwhacking.blogspot.com/2011/03/bfsize-print-file-size-in-bytes-and.html
En mi opinión, las dos formas más limpias con las herramientas comunes de Linux son:
Pero simplemente no quiero escribir parámetros o canalizar la salida solo para obtener un tamaño de archivo, así que estoy usando mi propio bfsize.
fuente
stat
es una opción para ellos.wc -c
toma 4090 mseg en un archivo de 10 MB en lugar de "0" msegstat -c %s
, así que estoy de acuerdo en que es útil tener soluciones alternativas incluso cuando no responden la pregunta exacta planteada.stat -c %s /usr/bin/stat
stat: illegal option -- c
usage: stat [-FlLnqrsx] [-f format] [-t timefmt] [file ...]
Aunque
du
normalmente imprime el uso del disco y no el tamaño real de los datos, las coreutils de GNUdu
pueden imprimir el "tamaño aparente" del archivo en bytes:Pero no funcionará con BSD, Solaris, macOS, ...
fuente
brew install coreutils
ygdu -b
logrará el mismo efectowc
necesita leer todo el archivo antes de dar un resultado,du
es inmediato.du -b
en un contexto completamente diferente en ladu
razón de ser .lstat
llamada, por lo que su rendimiento no depende del tamaño del archivo. Más corto questat -c '%s'
, pero menos intuitivo y funciona de manera diferente para las carpetas (imprime el tamaño de cada archivo dentro).du
puede acercarse usandodu -A -B1
, pero aún imprime el resultado en múltiplos de 1024B bloques. No logré que imprimiera el recuento de bytes. Incluso la configuraciónBLOCKSIZE=1
en el entorno no ayuda, porque entonces se utilizan bloques 512B.Finalmente decidí usar ls y la expansión de matriz bash:
no es realmente agradable, pero al menos solo hace 1 fork + execve, y no depende del lenguaje de programación secundario (perl / ruby / python / lo que sea)
fuente
ls -ln FILE | { read _ _ _ _ size _ && echo "$size"; }
no necesita bifurcaciones para el segundo paso de la canalización, ya que solo usa incorporados, sino que Bash 4.2.37 en Linux bifurca dos veces (aunque solo unaexecve
).read _ _ _ _ size _ <<<"$(exec ls -ln /usr/bin/wc)" && echo "$size"
funciona con un solo fork y single exec, pero usa un archivo temporal para here-string. Puede hacerse portátil reemplazando here-string por here-document compatible con POSX . Por cierto, tengaexec
en cuenta el en la subcapa. Sin eso, Bash realiza una bifurcación para el subshell y otra para el comando que se ejecuta dentro. Este es el caso del código que proporciona en esta respuesta. también.-l
es superfluo en presencia de-n
. Citando POSIXls
página de manual :-n
: Active la-l
opción (ELL), pero al escribir el propietario del archivo o grupo, escriba UID numérico del archivo o GID en lugar del nombre de usuario o grupo, respectivamente. Desactivar los-C
,-m
y-x
opciones.La solución más rápida multiplataforma (solo usa un solo fork () para ls , no intenta contar los caracteres reales, no genera awk, perl, etc. innecesarios).
Probado en MacOS, Linux; puede requerir una pequeña modificación para Solaris:
Si es necesario, simplifique los argumentos de ls y ajuste el desplazamiento en $ {__ ln [3]}.
Nota: seguirá los enlaces simbólicos.
fuente
Los BSD tienen
stat
opciones diferentes a las de GNU coreutils, pero capacidades similares.Esto funciona en macOS (probado en 10.12), FreeBSD , NetBSD y OpenBSD .
fuente
stat
utilidad.Al procesar la
ls -n
salida, como alternativa a las matrices de shell poco portátiles, puede usar los argumentos posicionales, que forman la única matriz y son las únicas variables locales en la shell estándar. Envuelva la sobrescritura de los argumentos posicionales en una función para preservar los argumentos originales de su script o función.Esto divide la salida de
ln -dn
segúnIFS
la configuración actual de la variable de entorno, la asigna a los argumentos posicionales y se hace eco del quinto. El-d
asegura que los directorios se manejen correctamente y-n
asegura que los nombres de usuarios y grupos no necesitan ser resueltos, a diferencia de con-l
. Además, los nombres de usuarios y grupos que contienen espacios en blanco podrían, en teoría, romper la estructura de línea esperada; por lo general, no se permiten, pero esta posibilidad aún hace que el programador se detenga y piense.fuente
Si usa
find
desde GNU fileutils:Desafortunadamente, otras implementaciones de
find
normalmente no admiten-maxdepth
ni-printf
. Este es el caso de, por ejemplo, Solaris y macOSfind
.fuente
size=$(test -f filename && find filename -printf '%s')
.-maxdepth
objetivo es evitar quefind
sea recursivo (yastat
que lo que el OP necesita reemplazar no lo es). A sufind
comando le falta un-name
y eltest
comando no es necesario.find
busca en sus parámetros de forma recursiva archivos que coincidan con los criterios dados. Si los parámetros no son directorios, la recursividad es ... bastante simple. Por lo tanto, primero pruebo quefilename
es realmente un archivo ordinario existente, y luego imprimo su tamaño usandofind
que no tiene ningún lugar para recurrir.find . -maxdepth 1 -type f -name filename -printf '%s'
sólo funciona si el archivo está en el directorio actual y aún puede examinar cada archivo en el directorio, lo que puede ser lento. Mejor uso (¡incluso más corto!)find filename -maxdepth 1 -type f -printf '%s'
.Puede usar el
find
comando para obtener un conjunto de archivos (aquí se extraen los archivos temporales). Luego, puede usar eldu
comando para obtener el tamaño de archivo de cada archivo en forma legible por humanos usando el-h
interruptor.SALIDA:
fuente
Tu primer ejemplo de Perl no me parece irrazonable.
Es por razones como esta que migré de escribir scripts de shell (en bash / sh, etc.) a escribir todos los scripts menos los más triviales en Perl. Descubrí que tenía que lanzar Perl para requisitos particulares y, a medida que lo hacía cada vez más, me di cuenta de que escribir los scripts en Perl era probablemente una forma más poderosa (en términos del lenguaje y la amplia gama de bibliotecas disponibles a través de CPAN ) y una forma más eficiente de lograr lo que quería.
Tenga en cuenta que otros lenguajes de secuencias de comandos de shell (por ejemplo, python / ruby) sin duda tendrán instalaciones similares, y es posible que desee evaluarlas para sus propósitos. Solo hablo de Perl porque ese es el lenguaje que uso y con el que estoy familiarizado.
fuente
si tiene Perl en su Solaris, utilícelo. De lo contrario, ls con awk es su siguiente mejor opción, ya que no tiene stat o su búsqueda no es GNU find.
fuente
Hay un truco en Solaris que he usado, si solicita el tamaño de más de un archivo, devuelve solo el tamaño total sin nombres, así que incluya un archivo vacío como / dev / null como segundo archivo:
por ejemplo, archivo de comando que desea / dev / null
No puedo recordar qué comando de tamaño funciona para ls / wc / etc; desafortunadamente no tengo una caja solaris para probarlo.
fuente
en Linux que puede usar
du -h $FILE
, ¿eso también funciona en Solaris?fuente
¿Probaste du -ks | awk '{imprimir $ 1 * 1024}'. Eso podría funcionar.
fuente