次のbashスクリプトを使用して、特定の拡張子(この場合は* .sh)のファイルのみをコピーしますが、それでもすべてのファイルにコピーされます。どうしましたか?
from = $ 1 to = $ 2 rsync -zarv --include = "*。sh" $ from $ to
rsync
ますか?これはシェルの内部で非常にうまく達成できますか?
次のbashスクリプトを使用して、特定の拡張子(この場合は* .sh)のファイルのみをコピーしますが、それでもすべてのファイルにコピーされます。どうしましたか?
from = $ 1 to = $ 2 rsync -zarv --include = "*。sh" $ from $ to
rsync
ますか?これはシェルの内部で非常にうまく達成できますか?
回答:
これらのファイルだけではなく、--include
によって除外されているファイルのサブセットを含めるために使用されていると思い--exclude
ます。言い換えれば、含めることは除外しないことの意味について考える必要があります。
代わりに試してください:
rsync -zarv --include "*/" --exclude="*" --include="*.sh" "$from" "$to"
rsyncバージョン3.0.6以降の場合、順序を次のように変更する必要があります(コメントを参照)。
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
-m
フラグを追加すると、宛先に空のディレクトリ構造が作成されなくなります。バージョン3.1.2でテスト済み。
したがって、*。shファイルのみが必要な場合は、すべてのファイルを除外し--exclude="*"
、すべてのディレクトリ--include="*/"
を含め、すべての* .shファイルを含める必要があります--include="*.sh"
。
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
。
--include=\*.sh
次に--exclude=\*
)
@chepnerによる回答では、ファイルが含まれているかどうかにかかわらず、事実に関係なくすべてのサブディレクトリがコピーされます。ファイルを含まず、ディレクトリ構造を保持しているサブディレクトリを除外する必要がある場合は、
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
さらにもう1つ:拡張子でファイルを1つのディレクトリのみ(再帰なしで)同期する必要がある場合は、次のような構造を使用する必要があります。
rsync -auzv --include './' --include '*.ext' --exclude '*' /source/dir/ /destination/dir/
最初のドットに注意してください--include
。--no-r
この構造では機能しません。
編集:
貴重なコメントをありがとうgbyte.co!
include
とexclude
彼らはで指定された順序でオプション。これに加えて、それは最初に一致した1で停止します。したがって、--exclude '*'
この例で最初にを指定した場合、rsyncは何もしません。詳細については、男性を参照してください。
-- include './'
は、ソースディレクトリパスにすべてを含めると言っていますか?次に、次の `--include '.ext'`は、指定されたソースパスに特定のファイルをインクルードし.ext
、excludeは他に何も送信しないと言います--exclude '*'
か?あれは正しいですか?
--include '*.ext'
--include '.ext'
manページの重要な部分は次のとおりです。
転送するファイル/ディレクトリのリストが作成されると、rsyncは転送する各名前をインクルード/除外パターンのリストに対して順番にチェックし、最初に一致したパターンが処理されます。除外パターンの場合、そのファイルはスキップされました。インクルードパターンの場合、そのファイル名はスキップされません。一致するパターンが見つからない場合、ファイル名はスキップされません。
要約する:
また、スラッシュで終わるものは、(一致するようfind -type d
に)ディレクトリに一致します。
この答えを上から引き離してみましょう。
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
.sh
ファイルをスキップしないでください最後に、--prune-empty-directories
は最初のルールがいたるところに空のディレクトリを作成しないようにします。
この便利な関数を書いて、私のbashスクリプトまたはに入れてください~/.bash_aliases
。Linuxでbashを使用してローカルで同期をテストし、awk
インストールしました。できます
selrsync(){
# selective rsync to sync only certain filetypes;
# based on: https://stackoverflow.com/a/11111793/588867
# Example: selrsync 'tsv,csv' ./source ./target --dry-run
types="$1"; shift; #accepts comma separated list of types. Must be the first argument.
includes=$(echo $types| awk -F',' \
'BEGIN{OFS=" ";}
{
for (i = 1; i <= NF; i++ ) { if (length($i) > 0) $i="--include=*."$i; } print
}')
restargs="$@"
echo Command: rsync -avz --prune-empty-dirs --include="*/" $includes --exclude="*" "$restargs"
eval rsync -avz --prune-empty-dirs --include="*/" "$includes" --exclude="*" $restargs
}
より多くの引数を追加したい場合(つまり--dry-run
)は、短くて便利で拡張可能です。
selrsync 'tsv,csv' ./source ./target --dry-run