展開せずに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
さんはchksum
though-非常に簡単です:
chksum
フィールドは、ヘッダー論理レコード内のすべてのオクテットの単純合計の8進値のISO / IEC 646:1991標準IRV表現でなければなりません。ヘッダーの各オクテットは、符号なしの値として扱われます。これらの値は、符号なし整数に追加され、ゼロに初期化されます。精度は17ビット以上です。チェックサムを計算するとき、chksum
フィールドはすべて<スペース>文字であるかのように扱われます。もちろん、実際にそれを実行する必要はありません。tar
既にそれを実行できます。つまり、それが実行することです。したがって、アーカイブを検索してファイルを抽出するために、それを使用する必要があるでしょう。そうすることで、あなたが何をしているのかを知っている場合と比べて、それが何よりも大きく異なることはありません。とにかく、なぜあなたはどうすべきですか?