web-dev-qa-db-ja.com

ファイルを分割した後で再度結合する最良の方法は何ですか?

大きなファイルがあり、100メガバイトのチャンクに分割する必要がある場合は、

split -b 100m myImage.iso

それは通常私に何かを与える

xaa
xab
xac
xad

そして、それらを一緒に戻すために、私は使用しています

cat x* > myImage.iso

catを使用してファイルのグループ内のコードの各行を読み取り、出力を新しいファイルにリダイレクトするよりも効率的な方法があるはずです。 2つのファイルを開くだけの方法のように、最初のファイルからEOFマーカーを削除し、それらを接続します。すべての内容を調べる必要はありません。

Windows/DOSには、バイナリファイルのコピーコマンドがあります。ヘルプには、このコマンドは複数のファイルを結合できるように設計されていると記載されています。次の構文で機能します:(/bはバイナリモード用です)

copy /b file1 + file2 + file3 outputfile

Linuxで大きなファイルを結合するのに、猫よりも似た、またはより良い方法はありますか?

更新

catは実際にはファイルを結合するための正しい方法であり最良の方法であるようです。私がずっと正しいコマンドを使っていたことを嬉しく思います:)皆さんのフィードバックに感謝します。

79
cwd

それがcatの目的です。最古のGNUツールの1つであるため、他のツールがこれより高速/優れた機能を発揮することはほとんどありません。パイピング-出力をリダイレクトするだけです。

54
rozcietrzewiacz

フードの下

最初のファイルをコピーし、その後に2番目のファイルをコピーする、というように効率的な方法はありません。 DOS copycatの両方がこれを行います。

各ファイルは、ディスク上の他のファイルとは独立して保存されます。ディスクのようなデバイスにデータを格納するように設計されたほとんどすべてのファイルシステムは、ブロックで動作します。これは、何が起こるかを非常に単純化した表現です。ディスクは、たとえば1kBのブロックに分割され、各ファイルについて、オペレーティングシステムはそれを構成するブロックのリストを保存します。ほとんどのファイルは整数ブロック長ではないため、最後のブロックは部分的にしか使用されていません。実際には、ファイルシステムには、いくつかのファイル間で最後の部分ブロックを共有したり、「ブロック46798、ブロック46799、…」ではなく「ブロック46798〜47913」を格納するなど、多くの最適化があります。オペレーティングシステムが新しいファイルを作成する必要がある場合、空きブロックを探します。ブロックは連続している必要はありません。ブロック4、5、98、178だけが空いている場合でも、4kBファイルを保存できます。バイトレベルまで下げるのではなく、ブロックを使用すると、新しいファイルまたは拡大するファイルの空きブロックを非常に速く見つけることができ、多くのファイルを作成または拡大および削除または縮小するときの断片化による問題が軽減されます(穴)。

中間ファイルで部分ブロックをサポートすることもできますが、特にファイルに非順次アクセスする場合は、かなり複雑になります。10340番目のバイトにジャンプするには、11番目のブロックの100番目のバイトにジャンプできません。介在するすべてのブロックの長さをチェックします。

ブロックを使用すると、一般的に最初のファイルがブロックの途中で終了するため、2つのファイルを結合することはできません。もちろん、特別なケースが考えられますが、連結時に両方のファイルを削除したい場合のみです。これは、まれな操作では非常に特殊な処理になります。典型的なファイルシステムでは、多くのファイルが同時にアクセスされているため、このような特別な処理はそれだけでは機能しません。したがって、最適化を追加する場合は、慎重に考える必要があります。他のプロセスが関連するファイルの1つを読み取っている場合はどうなりますか?誰かがAとCを連結しているときに誰かがAとBを連結しようとするとどうなりますか?等々。全体として、このまれな最適化は大きな負担になります。

全体として、他の場所で大きな犠牲を払わなければ、ファイルの結合をより効率的にすることはできません。それはそれだけの価値はありません。

分割と結合について

splitおよびcatは、ファイルを分割および結合する簡単な方法です。 splitは、cat *が結合に機能するように、アルファベット順に名前が付けられたファイルを生成します。

参加する場合のcatの欠点は、一般的な障害モードに対して堅牢ではないことです。ファイルの1つが切り捨てられているか欠落している場合、catは文句を言わず、破損した出力しか得られません。

zipsplitrar -vなどのマルチパートアーカイブを生成する圧縮ユーティリティがあります。分割に加えて圧縮(および複数のファイルを1つにアセンブル)する(そして逆に、結合に加えてアンパックおよび圧縮解除する)ため、これらは非常に一元的ではありません。しかし、それらは、すべてのパーツが揃っていること、およびパーツが完全であることを確認するのに役立ちます。

すべてのコンテンツをシステムのstdin/stdoutにパイプするよりも効率的な方法があるはずです

それが実際に起こっていることではないことを除いて。シェルはcat直接のstdoutを開いているファイルに接続しています。つまり、「stdoutを通過する」ことはディスクに書き込むことと同じです。

私はかつてこの問題を抱えていました。いくつかのファイルを結合したいのですが、それらを二重に保持するのに十分なディスク領域がありませんでした。

だから私はたくさんのプログラムを書いた:

  • 1つは、ファイルを読み取り、それをstdoutに送信し、完了した場合は削除することによって、ファイルを「吸い上げる」
  • 1つは「オンザフライ」でデータをバッファリングするためのものです。

これにより、次のようなことができるようになりました

partto sourcefile | mybuffer 128M >>cumufile

したがって、128Mがまだ書き込まれていないときにソースファイルを削除します。少し危険ですが、データがそれほど貴重ではない場合、またはデータが他の場所にも存在する場合は、実行可能です。

必要に応じて、ソースを提供できます。

3
glglgl

ファイル分割

サイズで分割

大きなファイルを小さなファイルに分割し、小さな出力ファイルの名前とサイズを選択する場合は、これが方法です。

split -b 500M videos\BigVideoFile.avi SmallFile.

このようにして、1つの大きなファイルを500 MBの小さな部分に分割することを選択します。また、パーツファイルの名前がSmallFileであることも必要です。ファイル名の後にドットが必要であることに注意してください。その結果、次のような新しいファイルが生成されます。

SmallFile.ab SmallFile.ad SmallFile.af SmallFile.ah SmallFile.aj
SmallFile.aa SmallFile.ac SmallFile.ae SmallFile.ag SmallFile.ai SmallFile.ak
...

行数で分割

このようにして、テキストファイルを50行に制限された小さなファイルに分割します。

split -l 50 text_to_split.txt

結果は次のようになります。

xaa xab xac ...

バイトごとに分割

バイト単位のカスタムファイルサイズの小さなファイルに分割:

split -b 2048 BigFile.mp4

結果は、Spliting By Number Of Linesの結果と同様になります。

ファイル結合

ファイルを結合するには2つの方法があります。最初のものは:

cat SmallFile.* > OutputBigVideoFile.avi

または:

cat SmallFile.?? > OutputBigVideoFile.avi

注:ファイルを結合する場合、小さなファイルは損傷しないはずです。また、すべての小さな(パーツ)ファイルは同じディレクトリにある必要があります。

1
Nole

技術的には、これは内容全体を読み書きする必要なくファイル全体にアクセスする方法であり、巨大なファイルやスペースが少ない場合に役立ちます。

$ mkfifo myImage.iso
$ cat xa{a..g} > myImage.iso &

そしてmyImage.iso、 例えば

$ md5sum myImage.iso

もちろんmyImage.isoは特別なファイル(名前付きパイプ)であり、通常のファイルではないため、これは、何をしようとしているかに応じて役立つ場合とそうでない場合があります。

0
golimar