cpで使用するためのzsh globbingモードの変更

cpで使用するためのzsh globbingモードの変更

ファイルではなく特定のフォルダからファイルを再帰的にコピーするスクリプトを作成しようとしています。A.extnB/*.extnディレクトリであり、いくつかの一般的な拡張子です。これが私が持っているものです:C/*BCextn

#!/usr/local/bin/zsh
setopt EXTENDED_GLOB
TMPDIR=/tmp/test

cp -pR $(dirname $0)/**~(*.foo/*|*/bar.txt|*.abc|qux.txt) $TMPDIR

しかし、予想通りパターンが否定されるわけではありません。私はその理由を知っていると思います。モードが正しい場合でも(表示されているようにecho)、cp -Rモードを知らずに「すべきではない」ディレクトリに入り、そのディレクトリに入るとモードは機能しなくなります。

目的の効果を得るには、上記の内容をどのように修正する必要がありますか?私はfindそれが可能だと思いますxargsが、上記の明確さに魅力を感じ、同様のものを好みます(しかし、これが間違ったアプローチであれば、他の解決策に非常に満足するでしょう)。

答え1

そうですね。cp実行前にモードが拡張されているため、コマンドは不明です。

代わりに--parentsオプションを使用して目的を達成できます。これはパターンに一致するファイルのみをコピーしますが、末尾のファイル名だけでなく、指定されたフルパス名も使用します。cp-R

ただし、このオプションは移植可能ではありません。 AFAIK、GNUバージョンのcpのみをサポートしています。

答え2

パターンはコピーしたくないファイルを除外できますが、そのファイルを含むディレクトリは除外せず、cp繰り返しコピーするように指示します。したがって、ファイルはとにかくコピーされます。これより悪いのは、このようなソースツリーがある場合です。

foo
foo/bar.txt
hello
hello/world
hello/world/wibble.txt

その後、パターンが展開され、次のfoo hello hello/world hello/world/wibble.txtファイルが生成されます$TMPDIR

foo
foo/bar.txt
hello
hello/world
hello/world/wibble.txt
wibble.txt
world
world/wibble.txt

これは「もはや無効」パターンとは関係ありません。このモードはシェルによって拡張され、ファイルのcpリストのみが表示されます。

再帰パトロールの実行中にファイルを除外できるコピーツールを使用する必要があります。

この目的のために zcp を使用できますが、ディレクトリをコピーせず、ターゲットディレクトリを自動的に作成することもありません。これを行うための最も簡単なツールはrsyncです。公園は別のオプションです。

rsync -a --exclude='*.foo/*' --exclude='bar.txt' --exclude='*.abc' --exclude='/qux.txt' $(dirname $0) $TMPDIR

関連情報