出力が tar に供給されると、「find」のフィルタは無視されます。

出力が tar に供給されると、「find」のフィルタは無視されます。

次のディレクトリ構造があります。

test/
test/1/
test/foo2bar/
test/3/

文字列「1」または「2」を含むサブディレクトリ(深さは事前定義されていません)のすべてのエントリを除いて、「test」ディレクトリを圧縮したいと思います。私が使用したいbashシェルから探す出力アスファルト。私は初めてテストします。探す:

find test/ -not -path "*1*" -not -path "*2*"

出力:

test/
test/3

途方もない。だから私はそれを組み合わせるアスファルト:

find test/ -not -path "*1*" -not -path "*2*" | tar -czvf test.tar.gz --files-from -

出力:

test/
test/3/
test/1/
test/foo2bar/
test/3/

実際、アーカイブには「test/1」と「test/foo2bar」の両方が存在します。これらのパラメータがfind出力に表示されてはいけない場合、なぜtarに渡されるのですか?

答え1

@cuonglmが言った内容を拡張するために、基本的にtar再帰的に動作します。ディレクトリ名を渡すとアーカイブされます。コンテンツこのディレクトリの。

findディレクトリではなくファイル名のみを返すようにコマンドを変更できます。

find test/ -type f -not -path "*1*" -not -path "*2*" |
tar -czvf test.tar.gz --files-from -

この--no-recursionフラグを使用して、次のことができますtar

find test/ -not -path "*1*" -not -path "*2*" | 
tar -czvf test.tar.gz --no-recursion --files-from - 

結果:

test/
test/3/

この--no-recursionフラグはGNU tarにのみ適用されます。他の機能を使用している場合は、該当するマニュアルページを参照して、同様の機能が利用可能であることを確認してください。

あなたのfind命令は除外されます。文書パスとディレクトリに含まれています12

答え2

--excludeGNU tarを使用すると、このオプションを使用して名前に基づいてファイルを除外することもできます。

$ tar --exclude "*1*" --exclude "*2*" -cvf foo.tar  test/
test/
test/3/

また-X、または--exclude-from除外パターンを読み取るにはファイルが必要です。


同様に、名前にまたはを含むファイルfind -not -path "*1*"も除外されます。スキップするだけ12目次find -pruneその名前は、および以下を使用してパターンと一致しますtar --no-recursion

$ touch test/3/blah.1
$ find test/ -type d \( -name "*1*" -o -name "*2*" \) -prune -o -print |
   tar cvf test.tar --files-from - --no-recursion
test/
test/3/
test/3/blah.1

(少なくともGNU tarとFreeBSD tarはそうです--no-recursion

関連情報