GNU/Linux >> Tutoriales Linux >  >> Linux

Cat Command en Linux:ejemplos esenciales y avanzados

Continuando con el recorrido por los comandos no tan conocidos que comenzamos la semana pasada con el comando ls, examinemos hoy el cat comando.

El cat nombre significa catenate ya que el trabajo principal de ese comando es unir varios archivos de entrada enviando secuencialmente su contenido en la salida estándar:

# Let's obtain first some sample data files:
curl -so - dict://dict.org/'d:felidae:gcide' | unexpand -a -t 3 |
  sed -Ee '/^151/,/^[.]/!d;/^[.0-9]/s/.*//' > felidae.txt
curl -so - dict://dict.org/'d:felis:gcide' | unexpand -a -t 3 |
  sed -Ee '/^151/,/^[.]/!d;/^[.0-9]/s/.*//' > felis.txt

# Catenate files
cat felidae.txt felis.txt

Si desea almacenar el resultado de esa concatenación en un archivo, debe usar una redirección de shell:

cat felidae.txt felis.txt > result.txt
cat result.txt

Incluso si su principal objetivo de diseño es encadenar archivos, el cat La utilidad también se emplea a menudo con un solo argumento para mostrar el contenido de ese archivo en la pantalla, exactamente como lo hice en la última línea del ejemplo anterior.

A. Usando el comando cat con entrada estándar

Cuando se usa sin ningún argumento, el cat El comando leerá los datos de su entrada estándar y los escribirá en su salida estándar, lo que en su mayoría es inútil... a menos que esté usando alguna opción para transformar los datos. Hablaremos de un par de opciones interesantes más adelante.

Además de las rutas de archivo, el cat El comando también entiende el - nombre de archivo especial como un alias para la entrada estándar. De esa forma, puede insertar los datos leídos desde la entrada estándar entre los archivos proporcionados en la línea de comando:

# Insert a separator between the two concatenated files
echo '----' | cat felis.txt - felidae.txt

B. Usando el comando cat con archivos binarios

1. Unirse a archivos divididos

El cat El comando no hace ninguna suposición sobre el contenido del archivo, por lo que funcionará felizmente con datos binarios. Algo que puede ser útil para volver a unir archivos rotos por el split o csplit dominio. O para unir descargas parciales como lo haremos ahora:

#
# A picture by Von.grzanka (CC-SA 3.0)
# Optimize bandwidth usage by breaking the download in two parts
# (on my system, I observe a 10% gain that way compared to a "full" download)
curl -s -r 0-50000 \
    https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Felis_catus-cat_on_snow.jpg/1024px-Felis_catus-cat_on_snow.jpg \
    -o first-half &
curl -s -r 50001- \
    https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Felis_catus-cat_on_snow.jpg/1024px-Felis_catus-cat_on_snow.jpg \
    -o second-half &
wait

Ahora tenemos dos mitades de una imagen. Puede abrir la primera mitad y ver que está "rota" usando la display de ImageMagick , o gimp , o cualquier otro software capaz de leer archivos de imagen:

display first-half
# -or-
gimp first-half
# -or-
firefox first-half

Si estudias el curl comando que usé, ves que las dos partes son perfectamente complementarias. La primera mitad es del byte 0 al 50000 y la segunda mitad, del byte 50001 al final del archivo. No debe haber datos faltantes entre ellos. Así que solo tenemos que catenar las dos partes juntas (en el orden correcto) para recuperar el archivo completo:

cat first-half second-half > image.jpg
display image.jpg

2. Trabajar con formatos de archivo que se pueden transmitir

No solo puedes usar el cat comando para "volver a unir" archivos binarios que se dividieron en varias partes, pero en algunos casos, también puede crear nuevo archivos de esa manera. Eso funciona particularmente bien con formatos de archivo "sin encabezado" o "transmitibles" como archivos de video de flujo de transporte MPEG (.TS archivos):

# Let's make a still video file from our picture
ffmpeg -y -loop 1 -i cat.jpg -t 3  \
    -c:v libx264 -vf scale=w=800:h=-1 \
    still.ts

# Let's make a fade-in from the same picture
ffmpeg -y -loop 1 -i cat.jpg -t 3  \
    -c:v libx264 -vf scale=w=800:h=-1,fade=in:0:75 \
    fadein.ts

# Let's make a fade-out from the same picture
ffmpeg -y -loop 1 -i cat.jpg -t 3  \
    -c:v libx264 -vf scale=w=800:h=-1,fade=out:0:75 \
    fadeout.ts

Ahora podemos combinar todos esos archivos de video de flujo de transporte usando el cat comando, obteniendo un archivo TS perfectamente válido en la salida:

cat fadein.ts still.ts fadeout.ts > video.ts
mplayer video.ts

Gracias al formato de archivo TS, puede combinar esos archivos en el orden que desee, e incluso puede usar el mismo archivo varias veces en la lista de argumentos para crear bucles o repeticiones en el video de salida. Obviamente, esto sería más divertido si usáramos imágenes animadas, pero te dejaré hacerlo por ti mismo:muchos dispositivos de nivel de consumidor graban archivos TS y, si no lo hacen, aún puedes usar ffmpeg para convertir casi cualquier archivo de video en un archivo de flujo de transporte. ¡No dudes en compartir tus creaciones usando la sección de comentarios!

3. Hackear archivos cpio

Como último ejemplo, veamos cómo podemos usar el cat comando para combinar varios cpio archivo. Pero esta vez, no será tan sencillo ya que requerirá un poco de conocimiento sobre el cpio formato de archivo de almacenamiento.

Un cpio El archivo almacena los metadatos y el contenido del archivo de forma secuencial, lo que lo hace adecuado para la concatenación a nivel de archivo con cat utilidad. Desafortunadamente, el cpio El archivo también contiene un tráiler utilizado para marcar el final del archivo:

# Create two genuine CPIO `bin` archive:
$ find felis.txt felidae.txt | cpio -o > part1.cpio
2 blocks
$ echo cat.jpg | cpio -o > part2.cpio
238 blocks

$ hexdump -C part1.cpio | tail -7
000002d0  2e 0d 0a 09 09 20 20 5b  57 6f 72 64 4e 65 74 20  |.....  [WordNet |
000002e0  31 2e 35 5d 0d 0a 0a 00  c7 71 00 00 00 00 00 00  |1.5].....q......|
000002f0  00 00 00 00 01 00 00 00  00 00 00 00 0b 00 00 00  |................|
00000300  00 00 54 52 41 49 4c 45  52 21 21 21 00 00 00 00  |..TRAILER!!!....|
00000310  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400
$ hexdump -C part2.cpio | tail -7
0001da40  46 96 ab f8 ad 11 23 90  32 79 ac 1f 8f ff d9 00  |F.....#.2y......|
0001da50  c7 71 00 00 00 00 00 00  00 00 00 00 01 00 00 00  |.q..............|
0001da60  00 00 00 00 0b 00 00 00  00 00 54 52 41 49 4c 45  |..........TRAILE|
0001da70  52 21 21 21 00 00 00 00  00 00 00 00 00 00 00 00  |R!!!............|
0001da80  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
0001dc00

La buena noticia es que, con los archivos binarios de cpio, ese tráiler tiene una longitud fija de 280 bytes. Entonces, usando el head comando estándar, tenemos una manera fácil de eliminarlo:

# Each archive end with the 280-byte trailer.
# To catenate both archives, just remove the trailer
# at the end of the first part:
$ head -c-280 part1.cpio | cat - part2.cpio > cat.cpio
$ cpio -it < cat.cpio
felis.txt
felidae.txt
cat.jpg
239 blocks

C. Opciones esenciales de comando cat

Después de haber jugado con varios formatos de archivos binarios, volvamos ahora a los archivos de texto simples estudiando un par de opciones diseñadas específicamente para manejar esos archivos. Si bien no forman parte del estándar POSIX, esas opciones son portátiles a través de BSD y GNU cat implementaciones. Tenga en cuenta que no pretendo ser exhaustivo aquí, así que verifique el man para ver la lista completa de opciones admitidas por cat en su sistema!

-n :rectas numéricas

Con el n opción, el cat El comando prefijará cada línea de salida por su número de línea:

cat -n felidae.txt
     1
     2    Felidae \Felidae\ n.
     3       a natural family of lithe-bodied round-headed fissiped
     4       mammals, including the cats; wildcats; lions; leopards;
     5       cheetahs; and saber-toothed tigers.
     6
     7       Syn: family {Felidae}.
     8            [WordNet 1.5]
     9

El -n números de opción salida líneas. Eso significa que el contador no restablecer al cambiar de un archivo de entrada al siguiente, como lo verá si prueba el siguiente comando usted mismo:

cat -n feli*.txt

-s :suprimir líneas de salida vacías repetidas

Con -s opción, el cat El comando colapsará varias líneas vacías consecutivas en una sola:

 cat -n felis.txt felidae.txt | sed -n 8,13p
     8       lynx ({Felis lynx}) is also called {Lynx lynx}.
     9       [1913 Webster +PJC]
    10
    11
    12    Felidae \Felidae\ n.
    13       a natural family of lithe-bodied round-headed fissiped
[email protected]:~$ cat -ns felis.txt felidae.txt | sed -n 8,13p
     8       lynx ({Felis lynx}) is also called {Lynx lynx}.
     9       [1913 Webster +PJC]
    10
    11    Felidae \Felidae\ n.
    12       a natural family of lithe-bodied round-headed fissiped
    13       mammals, including the cats; wildcats; lions; leopards;

En el ejemplo anterior, puede ver, en la salida predeterminada, las líneas 10 y 11 estaban vacías. Al agregar el -s opción, la segunda línea vacía fue descartada.

-b :número solo líneas no vacías

Algo relacionado con las dos opciones anteriores, el -b opción numerará líneas, pero ignorando las vacías:

$ cat -b felidae.txt | cat -n
     1
     2         1    Felidae \Felidae\ n.
     3         2        a natural family of lithe-bodied round-headed fissiped
     4         3        mammals, including the cats; wildcats; lions; leopards;
     5         4        cheetahs; and saber-toothed tigers.
     6         5
     7         6        Syn: family {Felidae}.
     8         7              [WordNet 1.5]
     9

El ejemplo anterior usa dos instancias de cat Comando con diferentes opciones en una canalización. La numeración interna proviene de -b opción usada con el primer cat dominio. La numeración exterior proviene de -n opción utilizada con el segundo cat .

Como puede ver, la primera y la última línea fueron not numerado por -b opción porque están vacíos. Pero, ¿qué pasa con la sexta línea? ¿Por qué todavía se numera con -b? ¿opción? Bueno, porque es un espacio en blanco línea, pero no un vacío uno, como veremos en la siguiente sección.

-v , -e , -t :mostrar caracteres no imprimibles

Las tres opciones -v , -e `, and `-t se utilizan para mostrar diferentes conjuntos de caracteres invisibles. Incluso si los conjuntos se superponen, no existe una opción "catch-all", por lo que tendrá que combinarlos si desea mostrar todos caracteres invisibles.

-v :ver caracteres invisibles

El -v opción mostrar todos los caracteres no imprimibles con intercalación y metanotación, excepto el salto de línea y la tabulación.

Con esa opción, los caracteres de control aparecerán como un signo de intercalación (^ ) seguido del carácter ASCII apropiado (por ejemplo, el retorno de carro, byte 13, se muestra como ^M porque M en ASCII es 64 + 13), y los caracteres con el conjunto de bits de orden superior aparecerán en notación "meta" M- seguido de la representación correspondiente a los 7 bits inferiores (por ejemplo, el byte 141 se mostrará como M-^M porque 141 es 128 + 13).

Aunque aparentemente esotérica, esa característica puede ser útil cuando se trabaja con archivos binarios, como, por ejemplo, si desea examinar la información sin procesar incrustada en un archivo JPEG:

$ cat -v cat.jpg | fold -75 | head -10
M-^?M-XM-^?M-`^@^PJFIF^@^A^A^A^@H^@H^@^@M-^?M-~^@QFile source: http://commo
ns.wikimedia.org/wiki/File:Felis_catus-cat_on_snow.jpgM-^?M-b^LXICC_PROFILE
^@^A^A^@^@^LHLino^B^P^@^@mntrRGB XYZ ^GM-N^@^B^@    ^@^F^@1^@^@acspMSFT
^@^@^@^@IEC sRGB^@^@^@^@^@^@^@^@^@^@^@^@^@^@M-vM-V^@^A^@^@^@^@M-S-HP  ^@^@^
@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^Qcprt^@^@^AP^@^@^@3desc^@^@^AM-^D^@^@^@lwtpt^@^@^AM-p^@^@^@^
Tbkpt^@^@^B^D^@^@^@^TrXYZ^@^@^B^X^@^@^@^TgXYZ^@^@^B,^@^@^@^TbXYZ^@^@^[email protected]^@^@
^@^Tdmnd^@^@^BT^@^@^@pdmdd^@^@^BM-D^@^@^@M-^Hvued^@^@^CL^@^@^@M-^Fview^@^@^
CM-T^@^@^@$lumi^@^@^CM-x^@^@^@^Tmeas^@^@^D^L^@^@^@$tech^@^@^D0^@^@^@^LrTRC^
@^@^D<^@^@^H^LgTRC^@^@^D<^@^@^H^LbTRC^@^@^D<^@^@^H^Ltext^@^@^@^@Copyright (

Otro caso de uso para -v La opción es encontrar caracteres de control que podrían haberse filtrado en un archivo de texto. Si lo recuerdas, tenemos ese extraño problema anterior con -b opción que numeraba la sexta línea de entrada, mientras que parecía como si estuviera vacío. Así que investiguemos eso:

$ cat -v felidae.txt
Felidae \Felidae\ n.^M
    a natural family of lithe-bodied round-headed fissiped^M
    mammals, including the cats; wildcats; lions; leopards;^M
    cheetahs; and saber-toothed tigers.^M
^M
    Syn: family {Felidae}.^M
          [WordNet 1.5]^M

¡Ah ah! Ves esos ^M ¿marcas? Se utilizan para reemplazar el carácter de retorno de carro que de otro modo sería invisible. ¿De dónde vino? Bueno, el dict El protocolo, como cualquier otro protocolo de Internet, utiliza CRLF como terminador de línea. Así que los descargamos como parte de nuestros archivos de muestra. Puede obtener más información sobre saltos de línea y retornos de carro en el fold y fmt artículo. Pero por ahora, explica por qué cat consideró que la sexta línea no estaba vacía.

-e :mostrar caracteres invisibles, incluido el final de línea

El -e la opción funciona como -v opción, excepto que también agregará un signo de dólar ($ ) antes de cada carácter de salto de línea, mostrando así explícitamente el final de las líneas:

$ cat -e felidae.txt
$
Felidae \Felidae\ n.^M$
    a natural family of lithe-bodied round-headed fissiped^M$
    mammals, including the cats; wildcats; lions; leopards;^M$
    cheetahs; and saber-toothed tigers.^M$
^M$
    Syn: family {Felidae}.^M$
          [WordNet 1.5]^M$
$

-t :muestra caracteres invisibles, incluidas las pestañas

El -t la opción funciona como -v opción, excepto que también mostrará tabulaciones usando el ^I notación de intercalación (la tabulación se almacena como un byte que contiene el valor 9, y I en ASCII es 64+9=73):

$ cat -t felidae.txt

Felidae \Felidae\ n.^M
^Ia natural family of lithe-bodied round-headed fissiped^M
^Imammals, including the cats; wildcats; lions; leopards;^M
^Icheetahs; and saber-toothed tigers.^M
^M
^ISyn: family {Felidae}.^M
^I^I  [WordNet 1.5]^M

-et :mostrar todos los caracteres ocultos

Como ya lo mencioné brevemente, si desea mostrar todos los caracteres no imprimibles, incluidas las tabulaciones y los marcadores de fin de línea, deberá usar tanto el -e y -t opciones:

$ cat -et felidae.txt
$
Felidae \Felidae\ n.^M$
^Ia natural family of lithe-bodied round-headed fissiped^M$
^Imammals, including the cats; wildcats; lions; leopards;^M$
^Icheetahs; and saber-toothed tigers.^M$
^M$
^ISyn: family {Felidae}.^M$
^I^I  [WordNet 1.5]^M$
$

Bonificación:El uso inútil del comando cat en Linux

Ningún artículo sobre el cat El comando estaría completo sin una mención del antipatrón "Uso inútil del gato".

Ocurre cuando usas cat con el único propósito de enviar el contenido de un archivo a la entrada estándar de otro comando. Ese uso del cat El comando se dice "inútil" ya que una simple redirección o un parámetro de nombre de archivo habría hecho el trabajo y lo habría hecho mejor. Pero un ejemplo que vale más que mil palabras:

$ curl -so - dict://dict.org/'d:uuoc:jargon' |    sed -Ee '/^151/,/^[.]/!d;/^[.0-9]/s/.*//'  > uuoc.txt
$ cat uuoc.txt | less

UUOC


    [from the comp.unix.shell group on Usenet] Stands for Useless Use of {cat};
    the reference is to the Unix command cat(1), not the feline animal. As
    received wisdom on comp.unix.shell observes, ?The purpose of cat is to
    concatenate (or ?catenate?) files. If it's only one file, concatenating it
    with nothing at all is a waste of time, and costs you a process.?
    Nevertheless one sees people doing


    cat file | some_command and its args ...

    instead of the equivalent and cheaper


    <file some_command and its args ...

    or (equivalently and more classically)


    some_command and its args ... <file
[...]

En el ejemplo anterior, utilicé una canalización para mostrar el contenido de uuoc.txt archivo con less localizador:

cat uuoc.txt | less

Entonces, el único propósito del cat El comando era alimentar la entrada estándar de less comando con el contenido de uuoc.txt expediente. Hubiera obtenido el mismo comportamiento usando una redirección de shell:

less < uuoc.txt

De hecho, el less El comando, como muchos comandos, también acepta un nombre de archivo como argumento. Así que simplemente podría haber escrito eso en su lugar:

less uuoc.txt

Como puede ver, no es necesario cat aquí. Si menciono el antipatrón “Useless Use of Cat”, es porque, si lo usas públicamente en un foro o en otro lugar, sin duda alguien te lo señalará con el argumento de que crearás un “proceso extra para nada”. ”

Debo admitir que durante mucho tiempo fui bastante desdeñoso con tales comentarios. Después de todo, en nuestro hardware moderno, generar un proceso adicional para una operación única no podría generar tanta sobrecarga.

Pero mientras escribía este artículo, hice un experimento rápido, comparando el tiempo requerido con y sin UUOC mediante una prueba awk script para procesar 500 MB de datos provenientes de un medio lento.

Para mi sorpresa, la diferencia estaba lejos de ser insignificante:

Sin embargo, la razón no se trata de que se cree un proceso adicional. Pero debido a la lectura/escritura adicional y al cambio de contexto en el que incurre el UUOC (como se puede inferir del tiempo dedicado a ejecutar el código del sistema). De hecho, cuando trabajas en grandes conjuntos de datos, ese cat extra El comando tiene un costo no despreciable. En cuanto a mí, ¡intentaré estar más atento con eso ahora! ¿Y usted? Si tienes ejemplos del uso inútil del gato, ¡no dudes en compartirlos con nosotros!


Linux
  1. Comando Cat de Linux:uso y ejemplos

  2. Comandos de Linux:descripción general y ejemplos

  3. Ejemplos importantes de comandos Cat en Linux

  4. Comando mv en Linux:7 ejemplos esenciales

  5. Ejemplos esenciales del comando de archivo en Linux

Buscar comando en Linux (Buscar archivos y directorios)

Comando lsof en Linux (10 ejemplos)

Opciones de comando y ejemplos de Tee Command en Linux

Ejemplos esenciales del comando ps en Linux

Ejemplos de comandos cat de Linux

Comando lsof en Linux con ejemplos