Tengo un archivo de texto que estoy enviando a una variable en mi script de shell. Sin embargo, solo necesito los primeros 50 caracteres.
He intentado usar cat ${filename} cut -c1-50
pero obtengo mucho más que los primeros 50 caracteres. Eso puede deberse a la cut
búsqueda de líneas (no 100% seguro), mientras que este archivo de texto podría ser una cadena larga, realmente depende.
¿Hay alguna utilidad en la que pueda canalizar para obtener los primeros caracteres X de un cat
comando?
|
?cat ${filename} | cut -c1-50
Respuestas:
Esto devuelve los primeros 50 bytes.
Tenga en cuenta que el comando no siempre se implementa de la misma manera en todos los sistemas operativos. En Linux y macOS se comporta de esta manera. En Solaris (11) necesita usar la versión gnu en / usr / gnu / bin /
fuente
-c
opción. Iría por dd (1) en su lugar.GNU coreutils 5.97
) sí.-c
Sin embargo, POSIX no se define como una opción válida, por lo que definitivamente depende de su entorno local. unix.com/man-page/posix/1/headSu
cut
comando funciona si usa una tubería para pasarle datos:O, evitando un uso inútil del gato y haciéndolo un poco más seguro:
Tenga en cuenta que los comandos anteriores imprimirán los primeros 50 caracteres (o bytes, según su
cut
implementación) de cada línea de entrada . Debería hacer lo que espera si, como usted dice, su archivo es una línea enorme.fuente
Esto devuelve los primeros 50 bytes.
fuente
status=none
bandera. Use en su2>/dev/null
lugar (y cite correctamente):dd if="$filename" bs=1 count=50 2>/dev/null
(aun así, considere usarbs=50 count=1
para reducir la cantidad de llamadas al sistema involucradas).status=none
cuando usa Ubuntu 14.04, coreutils 8.21, pero tiene derecho a usarlo2>/dev/null
si usa una versión anterior.read()
de 50 bytes. Si,file
por ejemplo, es una tubería y hay menos caracteres disponibles en ese momento, se devolverán menos bytes. Para tener el equivalente dehead -c50
, necesitarías usar el GNU específicoiflag=fullblock
.La mayoría de las respuestas hasta ahora suponen que 1 byte = 1 carácter, lo que puede no ser el caso si está utilizando una configuración regional no ASCII.
Una forma un poco más robusta de hacerlo:
Tenga en cuenta que esto supone:
ksh93
,bash
(o un recientezsh
omksh
(aunque el único conjunto de caracteres de varios bytes admitido pormksh
UTF-8 y solo despuésset -o utf8-mode
)) y una versión dehead
ese soporte-c
(la mayoría lo hace hoy en día, pero no estrictamente estándar).locale charmap
yfile -- "$filename"
para verificar eso); si no, configúrelo con ie.LC_ALL=en_US.UTF-8
)head
, asumiendo el peor de los casos UTF-8 donde todos los caracteres están codificados en un máximo de 4 bytes. Esto debería cubrir la mayoría de los casos que se me ocurren.fuente
head
, u otra implementación de la misma que agrega la-c
opción nōn-standard . Pero ya estás requiriendo GNU bash. (Nota:mksh
el modo UTF-8 podría hacer esto para los archivos codificados UTF-8). Le preguntaría al OP si requieren octetos o caracteres multibyte, solo "caracteres" es un término vago / genérico.$filename
o$testString
no contiene nueva línea en blanco o comodines o comienza con-
.${var:offset:length}
construcción que está utilizando aquí en realidad provieneksh93
y también es compatible con versiones recientes dezsh
(zsh
tiene la suya propia$testString[1,50]
). Necesitas${testString:0:50}
enksh93
yzsh
sin embargo.Otra variante (para la primera línea del archivo)
fuente
read
yecho
? Obash expansion
?grep
(regexp), y sí, el uso de shell aquí (pista: la primera línea puede ser grande). (Dicho esto, el bashism tampoco está en POSIX, pero la mayoría de los proyectiles lo implementan)1. Para archivos ASCII, haga como @DisplayName dice:
imprimirá los primeros 50 caracteres de file.txt, por ejemplo.
2. Para datos binarios, use
hexdump
para imprimirlos como caracteres hexadecimales:imprimirá los primeros 50 bytes de file.bin, por ejemplo.
Tenga en cuenta que sin la
-v
opción detallada,hexdump
reemplazaría las líneas repetidas con un asterisco (*
) en su lugar. Ver aquí: https://superuser.com/questions/494245/what-does-an-asterisk-mean-in-hexdump-output/494613#494613 .fuente
Puede usar sed para esto, que abordará el problema con bastante facilidad
fuente
sed -n -e '1s/^\(.\{50\}\).*/\1/p' ${filename}