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