展開せずにtarされたファイルの内容を表示したいのですが、シナリオ:a.tarがあり、その中にというファイルがあります./x/y.txt。y.txt実際にを抽出せずにのコンテンツを表示したいa.tar。
展開せずにtarされたファイルの内容を表示したいのですが、シナリオ:a.tarがあり、その中にというファイルがあります./x/y.txt。y.txt実際にを抽出せずにのコンテンツを表示したいa.tar。
回答:
おそらくGNU固有のオプションですが、-Oまたは--to-stdoutを使用してファイルを標準出力に抽出できます。
$ tar -axf file.tgz foo/bar -O
tar -axf file.tar.gz --wildcards --no-anchored '*read_this_file*' --Oたとえば、多くのファイルが一致する場合*read_this_file*。すべてが同じ行に印刷されます。から、man見つけました--to-command。したがって、パス--to-command="echo '' && cat"は少し黒魔術ですが、動作します:D
$ tar -axf file.tgz foo/bar -O
これにより、。/ x / y.txtの内容がa.tarからSTDOUTに出力されます。
tar xfO a.tar ./x/y.txt
これは簡単です
less a.tar:./x/y.txt
この手品は、lesspipeインストール済みで、env変数LESSOPENがlesspipeを正しくインストールし| /usr/bin/lesspipe.sh %sている場合に想定されるように定義されている場合に機能します。
lesspipe.shはおそらく好まれるはずです。
ああ、でもこれはファイル内のtarファイルの内容についての質問です。そして実際には、これはそれほど難しいことではありません。重要なのは、tarファイルは単にブロックされたストリームファイルです-アーカイブ内の各ファイルはその前のファイルの後に見つかり、各ファイルは指定された形式に基づいてメタデータヘッダーを取得します。
そのフォーマットに基づいて、私はかつて書いたshitar-それは数行のddシェルスクリプトでありtar、ブロックデバイスのストリームをその場で上向きに流すことができた。同じに基づいて、最近では、次の数行のコードを記述しました。
tar --no-recursion -c ./ |
{ printf \\0; tr -s \\0; } |
cut -d '' -f-2,13 |
tr '\0\n' '\n\t'
... tarその場でファイルを選択し、そのコンポーネントテキストファイルに対してインライン変換を実行するため。そこcutのフィールドは、フィールドを指す1,2,13 NUL区切りの ライン入力の。ファイルにテキストファイルのみが含まれている場合、そのようなことは簡単tarです。512バイトごとに1回発生する可能性がある)tarのレコード区切り文字は、NULごとに1つに絞り込んで削除できるため、発生回数をカウントする必要はありません。
tarのヘッダー形式は次のようになります。
field offset len
name 0 100
mode 100 8
uid 108 8
gid 116 8
size 124 12
mtime 136 12
chksum 148 8
typeflag 156 1
linkname 157 100
magic 257 6
version 263 2
uname 265 32
gname 297 32
devmajor 329 8
devminor 337 8
prefix 345 155
単純なtar操作の比較的容易な処理とアーカイブ形式の非常に複雑な側面との間には急勾配があることを理解してください。同種のファイルの小さなグループをまとめてパックしたり、タイプを予測できるメンバーのみを含むアーカイブを分割したりといった単純なことは、いくつかのシェルパイプで簡単に実行できますが、任意のアーカイブメンバーを確実に処理することは簡単なことではありません。
これらのメンバーに任意のバイナリデータが含まれている可能性がある場合は特に困難です。これにより、信頼できるアプリケーションが確実に除外されます。tr -sこの困難は、通常以外のさまざまなタイプのファイルや、ネイティブ以外の文字セットが使用されている場合や、元のアーカイブは、処理する準備ができていないフォーマットアプリケーションの特異性を持つ実装によって作成されました。そしてこれは、tarアーカイブタイプの基本的な標準化された側面にのみ触れています。拡張ヘッダーとフォーマット拡張、スパースファイルと圧縮を追加します。
ただし、基本に戻ると、アーカイブの標準のレコードサイズtarは20ブロック、つまり10240バイトです。ustarただし、標準のレコードサイズでブロックされ、標準のファイルタイプと標準のヘッダーのみが含まれているアーカイブのsize場合、メンバーフィールドに一致するメンバーが見つかるまでヘッダーフィールドに従って読み取りを行うことで、メンバーヘッダーからメンバーヘッダーにスキップする必要があります。あなたが求めるもの。そこにsize到達したら、ターゲットのメンバーヘッダーの末尾から始まるオフセットからバイト単位で読み取ります。そして、それはあなたのファイルです。
ただし、ヘッダーをスキップするのは簡単ではありません。異なるタイプには、に対応する実際のデータブロックが追加されるか、追加されませんsize。たとえば、ディレクトリとリンクにはそのようなデータブロックは含まれず、ヘッダーの説明のみが含まれるため、sizeスキップ式にフィールドを適用する必要があるかどうかを正確に確認する前に、現在のヘッダーのファイルタイプを確認する準備をする必要があります。
また、レコードサイズの要素-アーカイブメンバーのサイズが10240の標準レコードサイズとうまく同期するかどうかによって、それぞれに追加の0ブロックが追加される場合と追加されない場合があります。また、レコードのサイズはアーカイブの作成時に宣言できます。そのため、20ブロックになることもありませんが、仕様上、512バイト単位で常にブロックする必要があります。
tar交換フォーマット。詳細説明のセクションを参照してください。この形式の文字特殊アーカイブファイルのデフォルトのブロックサイズは10240です。実装は、512の倍数である32256以下のすべてのブロックサイズ値をサポートします。したがって、tar任意のバイナリデータを含む可能性のあるファイルを含む可能性のあるファイルを使用して作業している場合は、ファイルタイプに従って、アルゴリズム的にファイルをスキップする必要があります。スペックは言う:
sizeフィールドは、オクテット単位でファイルのサイズです。
typeflagフィールドは型にファイルを指定するために設定されている1 (リンク)または2 (シンボリックリンク)、sizeフィールドはゼロとして指定されなければなりません。typeflagフィールドはタイプのファイルを指定するように設定されている5 (ディレクトリ)、sizeそのレコード型の定義の下に記載したようにフィールドが解釈されなければなりません。typeflagフィールドが3 (文字特殊ファイル)、4 (ブロック特殊ファイル)、または6 (FIFO)に設定されている場合、フィールドの意味はsizeこのPOSIX.1-2008のボリュームでは規定されておらず、データ論理レコードはメディアに保存されます。sizeフィールドは読み取り時に無視されます。typeflagフィールドが他の値に設定され、ヘッダに続く記述された論理レコードの数でなければならない除算の結果の任意の部分を無視し、。( (size+ 511 ) / 512 )...そしてもちろん、各ヘッダーの個々のサイズも考慮します-これはメンバーごとの追加のブロックです。したがって、目的のヘッダーと一致するヘッダーに到達するまで、ヘッダーからヘッダーへの読み取りによる読み取りをスキップすることができます。このとき、現在のレコードが単にファイルまたは実際のファイルへのリンクを示しているかどうかを確認する必要があります。 。同じファイルがアーカイブに複数回追加された場合、実際のファイルのデータはアーカイブ内の別の場所に既に存在している可能性があるため、多くtarのにはリンクヘッダーのみが含まれるため、これは特に重要です。
計算をchksumフィールドに適用する必要があることを確認したら、自分が持っていると思うファイルが実際に必要なファイルであることを確認します。tarさんはchksumthough-非常に簡単です:
chksumフィールドは、ヘッダー論理レコード内のすべてのオクテットの単純合計の8進値のISO / IEC 646:1991標準IRV表現でなければなりません。ヘッダーの各オクテットは、符号なしの値として扱われます。これらの値は、符号なし整数に追加され、ゼロに初期化されます。精度は17ビット以上です。チェックサムを計算するとき、chksumフィールドはすべて<スペース>文字であるかのように扱われます。もちろん、実際にそれを実行する必要はありません。tar既にそれを実行できます。つまり、それが実行することです。したがって、アーカイブを検索してファイルを抽出するために、それを使用する必要があるでしょう。そうすることで、あなたが何をしているのかを知っている場合と比べて、それが何よりも大きく異なることはありません。とにかく、なぜあなたはどうすべきですか?