GNU/Linux >> Linux Esercitazione >  >> Linux

Cat Command in Linux:esempi essenziali e avanzati

Continuando il tour di quei comandi poco conosciuti iniziato la scorsa settimana con il comando ls, esaminiamo oggi il cat comando.

Il cat nome sta per catenate poiché il compito principale di quel comando è unire diversi file di input inviando in sequenza il loro contenuto sull'output standard:

# 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

Se vuoi memorizzare il risultato di quella concatenazione in un file, devi usare un reindirizzamento della shell:

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

Anche se il suo obiettivo di progettazione principale è concatenare i file, il cat l'utilità viene spesso utilizzata anche con un solo argomento per visualizzare il contenuto di quel file sullo schermo, esattamente come ho fatto nell'ultima riga dell'esempio sopra.

A. Utilizzo del comando cat con input standard

Se utilizzato senza alcun argomento, il cat il comando leggerà i dati dal suo input standard e li scriverà nel suo output standard, il che è per lo più inutile ... a meno che tu non stia usando qualche opzione per trasformare i dati. Parleremo di un paio di opzioni interessanti più avanti.

Oltre ai percorsi dei file, il cat il comando comprende anche - nome file speciale come alias per lo standard input. In questo modo, puoi inserire i dati letti dallo standard input tra i file forniti dalla riga di comando:

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

B. Utilizzo del comando cat con file binari

1. Unire file divisi

Il cat comando non fa alcuna ipotesi sul contenuto del file, quindi funzionerà felicemente con i dati binari. Qualcosa che potrebbe essere utile per ricongiungersi ai file interrotti dalla split o csplit comando. O per partecipare a download parziali come faremo ora:

#
# 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

Ora abbiamo due metà di un'immagine. Puoi aprire la prima metà e vedere che è "rotta" usando il display di ImageMagick o gimp , o qualsiasi altro software in grado di leggere file di immagine:

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

Se studi il curl comando che ho usato, si vede che le due parti sono perfettamente complementari. La prima metà va dal byte 0 a 50000 e la seconda metà dal byte 50001 alla fine del file. Non dovrebbero esserci dati mancanti tra di loro. Quindi dobbiamo solo concatenare le due parti insieme (nell'ordine corretto) per ottenere il file completo:

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

2. Lavorare con formati di file riproducibili in streaming

Non solo puoi usare il cat comando per "riunire" file binari che sono stati divisi in più parti, ma in alcuni casi puoi anche creare nuovi file in questo modo. Ciò funziona particolarmente bene con i formati di file "headerless" o "streamable" come i file video di flusso di trasporto MPEG (.TS file):

# 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

Ora possiamo combinare tutti quei file video di flusso di trasporto usando il cat comando, ottenendo un file TS perfettamente valido nell'output:

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

Grazie al formato di file TS, puoi combinare quei file nell'ordine desiderato e puoi persino utilizzare lo stesso file più volte nell'elenco degli argomenti per creare loop o ripetizioni nel video di output. Ovviamente, questo sarebbe più divertente se utilizzassimo immagini animate, ma te lo lascio fare da solo:molti dispositivi di livello consumer registrano file TS e, in caso contrario, puoi ancora utilizzare ffmpeg per convertire quasi tutti i file video in un file di flusso di trasporto. Non esitare a condividere le tue creazioni utilizzando la sezione commenti!

3. Hacking archivi cpio

Come ultimo esempio, vediamo come possiamo usare il cat comando per combinare più cpio archivi. Ma questa volta, non sarà così semplice poiché richiederà un po' di conoscenza del cpio formato del file di archivio.

Un cpio archivio memorizza i metadati e il contenuto del file in sequenza, il che lo rende adatto per la concatenazione a livello di file con il cat utilità. Sfortunatamente, il cpio archivio contiene anche un trailer utilizzato per segnare la fine dell'archivio:

# 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 buona notizia è che, con gli archivi binari cpio, il trailer ha una lunghezza fissa di 280 byte. Quindi, usando il head comando standard, abbiamo un modo semplice per rimuoverlo:

# 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. Opzioni essenziali per i comandi cat

Dopo aver giocato con vari formati di file binari, torniamo ora ai semplici vecchi file di testo studiando un paio di opzioni appositamente studiate per gestire quei file. Sebbene non facciano parte dello standard POSIX, queste opzioni sono trasferibili su BSD e GNU cat implementazioni. Tieni presente che non pretendo di essere esaustivo qui, quindi controlla il man per vedere l'elenco completo delle opzioni supportate da cat sul tuo sistema!

-n :linee numeriche

Con il n opzione, il cat il comando prefiggerà ogni riga di output con il suo numero di riga:

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

Il -n numeri di opzione output Linee. Ciò significa che il contatore non ripristina quando si passa da un file di input al successivo, come lo vedrai se provi da solo il seguente comando:

cat -n feli*.txt

-s :sopprime righe di output vuote ripetute

Con il -s opzione, il cat comando comprimerà più righe vuote consecutive in 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;

Nell'esempio sopra, puoi vedere, nell'output predefinito, le righe 10 e 11 erano vuote. Quando si aggiungono i -s opzione, la seconda riga vuota è stata eliminata.

-b :numera solo le righe non vuote

In qualche modo correlato alle due opzioni precedenti, -b l'opzione numererà le righe, ma ignorando quelle vuote:

$ 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

L'esempio sopra usa due istanze di cat comando con diverse opzioni in una pipeline. La numerazione interna deriva da -b opzione usata con il primo cat comando. La numerazione esterna deriva da -n opzione usata con il secondo cat .

Come puoi vedere, la prima e l'ultima riga erano non numerato dal -b opzione perché sono vuoti. Ma per quanto riguarda la 6a riga? Perché è ancora numerato con -b opzione? Bene, perché è un vuoto riga— ma non un vuoto uno, come vedremo nella prossima sezione.

-v , -e , -t :visualizza i caratteri non stampabili

Le tre opzioni -v , -e `, and `-t vengono utilizzati per visualizzare diversi set di caratteri invisibili. Anche se i set si sovrappongono, non esiste un'opzione "catch-all", quindi dovrai combinarli se desideri visualizzare tutti caratteri invisibili.

-v :visualizza i caratteri invisibili

Il -v opzione mostra tutti i caratteri non stampabili con accento circonflesso e meta notazione, tranne l'avanzamento riga e la tabulazione.

Con questa opzione, i caratteri di controllo appariranno come un accento circonflesso (^ ) seguito dal carattere ASCII appropriato (ad esempio, il ritorno a capo, byte 13, viene visualizzato come ^M perché M in ASCII è 64 + 13), e i caratteri con il bit di ordine superiore impostato appariranno nella notazione "meta" M- seguito dalla rappresentazione corrispondente ai 7 bit inferiori (es. il byte 141 verrà visualizzato come M-^M perché 141 è 128 + 13).

Sebbene apparentemente esoterica, questa funzione può essere utile quando si lavora con file binari, come, ad esempio, se si desidera esaminare le informazioni grezze incorporate in un file 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 (

Un altro caso d'uso per -v l'opzione è trovare i caratteri di controllo che potrebbero essere trapelati in un file di testo. Se te lo ricordi, abbiamo quello strano problema sopra con il -b opzione che numera la 6a riga di input, mentre sembrava come se fosse vuoto. Quindi esaminiamo questo:

$ 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! Vedi quei ^M segni? Vengono utilizzati per sostituire il carattere di ritorno a capo altrimenti invisibile. Da dove proviene? Bene, il dict Il protocollo, come qualsiasi altro protocollo Internet, utilizza CRLF come terminatore di linea. Quindi li abbiamo scaricati come parte dei nostri file di esempio. Puoi saperne di più sull'avanzamento riga e sui ritorni a capo nel fold e fmt articolo. Ma per ora, spiega perché cat considerata la sesta riga come non vuota.

-e :mostra i caratteri invisibili, incluso il fine riga

Il -e l'opzione funziona come -v opzione, tranne per il fatto che aggiungerà anche un simbolo del dollaro ($ ) prima di ogni carattere di avanzamento riga, mostrando così esplicitamente la fine delle righe:

$ 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 :mostra i caratteri invisibili, comprese le schede

Il -t l'opzione funziona come -v opzione, tranne per il fatto che visualizzerà anche le tabulazioni usando il ^I notazione caret (la scheda viene memorizzata come un byte contenente il valore 9 e I in ASCII è 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 :mostra tutti i caratteri nascosti

Come ho già accennato brevemente, se vuoi visualizzare tutti i caratteri non stampabili, inclusi sia le tabulazioni che i marcatori di fine riga, dovrai utilizzare sia il -e e -t opzioni:

$ 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$
$

Bonus:l'uso inutile del comando cat in Linux

Nessun articolo sul cat il comando sarebbe completo senza menzionare l'anti-modello "Uso inutile di Cat".

Si verifica quando usi cat al solo scopo di inviare il contenuto di un file allo standard input di un altro comando. Quell'uso del cat comando è detto "inutile" poiché un semplice reindirizzamento o un parametro del nome file avrebbe svolto il lavoro e lo avrebbe fatto meglio. Ma un esempio che vale più di mille parole:

$ 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
[...]

Nell'esempio sopra, ho utilizzato una pipeline per visualizzare il contenuto di uuoc.txt file con il less cercapersone:

cat uuoc.txt | less

Quindi, l'unico scopo del cat il comando doveva alimentare l'input standard di less comando con il contenuto del uuoc.txt file. Avrei ottenuto lo stesso comportamento usando un reindirizzamento della shell:

less < uuoc.txt

In effetti, il less comando, come molti comandi, accetta anche un nome file come argomento. Quindi avrei potuto semplicemente scriverlo invece:

less uuoc.txt

Come puoi vedere, non c'è bisogno di cat qui. Se cito l'anti-pattern "Useless Use of Cat", è perché, se lo usi pubblicamente su un forum o altrove, senza dubbio qualcuno ti farà notare che con l'argomento creerai un "processo extra per niente. ”

Devo ammettere che per molto tempo sono stato piuttosto sprezzante con tali commenti. Dopotutto, sul nostro hardware moderno, generare un processo aggiuntivo per un'operazione one-shot non potrebbe causare un sovraccarico.

Ma mentre scrivevo questo articolo, ho fatto un rapido esperimento, confrontando il tempo richiesto con e senza UUOC da un test awk script per elaborare 500 MB di dati provenienti da un supporto lento.

Con mia sorpresa, la differenza era tutt'altro che trascurabile:

Tuttavia, il motivo non riguarda la creazione di un processo aggiuntivo. Ma a causa della lettura/scrittura extra e del cambio di contesto incorre nell'UUOC (come si può dedurre dal tempo impiegato nell'esecuzione del codice di sistema). Quindi, in effetti, quando lavori su set di dati di grandi dimensioni, quel cat in più comando ha un costo non trascurabile. Quanto a me, cercherò di essere più vigile su questo ora! E tu? Se hai esempi dell'uso inutile del gatto non esitare a condividerli con noi!


Linux
  1. Comandi Linux - Panoramica ed esempi

  2. Esempi importanti di comandi Cat in Linux

  3. Come copiare file in Linux e Unix? 10 cp Esempi di comandi

  4. 10 esempi di comandi Cat per gestire i file in Linux / UNIX

  5. Esempi di comandi mkdir e rmdir in Linux

Trova comando in Linux (Trova file e directory)

lsof Command in Linux (10 esempi)

Opzioni di comando ed esempi di Tee Command in Linux

Esempi essenziali del comando ps in Linux

Esempi di comandi di Linux cat

lsof Command in Linux con esempi