Questo è proprio ciò che cat
è stato fatto per. Dal momento che è uno dei più vecchi strumenti GNU, penso che sia molto improbabile che qualsiasi altro strumento lo faccia più velocemente/meglio. E non è piping - sta solo reindirizzando l'output.
Sotto il cofano
Non c'è modo più efficiente che copiare il primo file, quindi copiare il secondo file dopo di esso e così via. Entrambi DOS copy
e cat
fallo.
Ogni file viene memorizzato indipendentemente dagli altri file sul disco. Quasi tutti i filesystem progettati per archiviare dati su un dispositivo simile a un disco funzionano a blocchi. Ecco una presentazione molto semplificata di ciò che accade:il disco è diviso in blocchi di, diciamo, 1kB, e per ogni file il sistema operativo memorizza l'elenco dei blocchi che lo compongono. La maggior parte dei file non è lunga un numero intero di blocchi, quindi l'ultimo blocco è occupato solo parzialmente. In pratica, i filesystem hanno molte ottimizzazioni, come la condivisione dell'ultimo blocco parziale tra più file o la memorizzazione di "blocchi da 46798 a 47913" anziché "blocco 46798, blocco 46799, ...". Quando il sistema operativo deve creare un nuovo file, cerca i blocchi liberi. I blocchi non devono essere consecutivi:se solo i blocchi 4, 5, 98 e 178 sono liberi, puoi comunque memorizzare un file da 4kB. L'uso di blocchi invece di scendere al livello di byte aiuta a trovare blocchi liberi per un file nuovo o in crescita notevolmente più veloce e riduce i problemi dovuti alla frammentazione quando crei o ingrandisci ed elimini o rimpicciolisci molti file (lasciando un numero crescente di fori).
Potresti supportare blocchi parziali a metà file, ma ciò aggiungerebbe una notevole complessità, in particolare quando si accede ai file in modo non sequenziale:per saltare al 10340esimo byte, non potresti più saltare al 100esimo byte dell'undicesimo blocco, avresti per controllare la lunghezza di ogni blocco intermedio.
Dato l'uso dei blocchi, non puoi semplicemente unire due file, perché in genere il primo file termina a metà blocco. Certo, potresti avere un caso speciale, ma solo se vuoi eliminare entrambi i file durante la concatenazione. Sarebbe una gestione altamente specifica per un'operazione rara. Tale gestione speciale non vive da sola, perché su un tipico filesystem si accede a molti file contemporaneamente. Quindi, se vuoi aggiungere un'ottimizzazione, devi pensare attentamente:cosa succede se qualche altro processo sta leggendo uno dei file coinvolti? Cosa succede se qualcuno cerca di concatenare A e B mentre qualcuno sta concatenando A e C? E così via. Tutto sommato, questa rara ottimizzazione sarebbe un peso enorme.
Tutto sommato, non puoi rendere più efficiente l'unione dei file senza fare grandi sacrifici altrove. Non ne vale la pena.
Sul dividere e unire
split
e cat
sono modi semplici per dividere e unire i file. split
si occupa di produrre file nominati in ordine alfabetico, in modo che cat *
funziona per l'adesione.
Uno svantaggio di cat
per l'unione è che non è robusto rispetto alle modalità di errore comuni. Se uno dei file è troncato o mancante, cat
non ti lamenterai, otterrai solo un output danneggiato.
Ci sono utilità di compressione che producono archivi multiparte, come zipsplit
e rar -v
. Non sono molto unixy, perché comprimono e impacchettano (assemblano più file in uno) oltre a dividere (e viceversa decomprimono e decomprimono oltre a unire). Ma sono utili in quanto verificano che tu abbia tutte le parti e che le parti siano complete.
Sembra che dovrebbe esserci un modo più efficiente rispetto al reindirizzamento di tutti i contenuti attraverso il
stdin
del sistema /stdout
Solo che non è proprio quello che sta succedendo. La shell sta collegando lo stdout di cat
direttamente al file aperto, il che significa che "passare attraverso stdout" equivale a scrivere su disco.