update2:退屈ですが、2番目の解決策を説明します。

update2:退屈ですが、2番目の解決策を説明します。

フォルダAをフォルダBに同期したいのですが、次の制限があります。

  • フォルダAには、何百ものフォルダに何千ものファイルと数百ギガバイトのファイルが含まれています。

  • フォルダBには、フォルダA(および必要なすべてのフォルダ)に最新の10 GB(または他の)ファイルが含まれており、フォルダAにある最新のファイルのファイルと構造を複製します。

  • 同期が実行されるたびに、フォルダBはフォルダAの最新の10GBファイルに制限され、古いファイルは削除されます。

  • 空のディレクトリはクリーンアップする必要がありますが、必要に応じて直接クリーンアップできます。

bashやOS X上で動作するより良いツールがある場合は、rsyncを介してこれを行う必要はありませんが、ログインセッションなしでスタンドアロンで実行できる必要があります。

答え1

#非推奨の場合は、コメントで理由を書き留めてください。本当に悪い!

私の意見で解決策を見つけました。

完全なコマンドラインは次のとおりです。 $ find . -type f -printf "%T@ %p %s\n"| sort -n -r | awk '{ i+=$3; if (i<=200000) {print $2}}' | tar -cvf toto.tar -T -&& ssh -n prd "rm -rf dir/*" && scp toto.tar prd:tmp/ && ssh -n prd "tar xvf tmp/toto.tar"

このコマンドはfindで始まり、現在のディレクトリ(サーバーAのディレクトリパスに合わせて調整する必要があります)からすべてのファイルを見つけ、3つのフィールドを印刷します。

  • %T @ Unixタイムスタンプ印刷
  • find%pは起動時にファイルパスを印刷します。
  • %s印刷ファイルサイズ(バイト)
  • \nもちろん新しい行です。

次に、出力がソートされ、最初のフィールドがfind数値のsort -n -r逆順に並べ替えられ、Unixタイムスタンプが最新のエントリから最も古いエントリの順にソートされます。

サイズ制限を処理するには、サイズの合計が制限を下回るまでawk出力の2番目のフィールドを印刷すると、少し役立ちます。sort処理する各行について、3番目のフィールド(サイズ)の値をローカル変数として合計iし、ソートされた出力の2番目のフィールドを印刷します(i制限より小さい場合)。

tar -cvf toto.tar -T -awk出力で提供されるファイルのリストから、toto.tarというアーカイブが作成されます。

成功したら、まずサーバーBのバックアップを削除してからファイルをリモートscp toto.tar host:dirサーバー(サーバーB)に転送ssh -n "tar xvf dir/toto.tarし、ディレクトリ構造を維持しながら転送されたアーカイブの圧縮をリモートフォルダに解凍します。

以前のscpベースのソリューションはディレクトリ構造を維持していなかったため、この回答を編集しました。

これは、最大サイズが200kbの私のhomedirで実行された結果です。

$ rm toto.tar; find . -type f -printf "%T@ %p %s\n"| sort -n -r | awk '{ i+=$3; if (i<=200000) {print $2}}'  | tar -cvf toto.tar -T -&& scp toto.tar prd:tmp/ && ssh -n prd "tar xvf tmp/toto.tar"
./.lesshst
./.viminfo
./scpplus
./.config/xfce4/desktop/icons.screen0-1350x650.rc
./.xsession-errors
./.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml
./.config/pulse/7f14833c645d4a6abb0beba68b79e0c0-default-source
./.config/pulse/7f14833c645d4a6abb0beba68b79e0c0-default-sink
./.cache/imsettings/log
./.cache/gpg-agent-info
./.ICEauthority
./.vboxclient-draganddrop.pid
./.vboxclient-seamless.pid
./.vboxclient-display.pid
./.vboxclient-clipboard.pid
./.dbus/session-bus/7f14833c645d4a6abb0beba68b79e0c0-0
./.cache/xscreensaver/xscreensaver-getimage.cache
./.config/xfce4/desktop/icons.screen0-1264x950.rc
./work/fpart-0.9.2/src/fpart
toto.tar                                                                                                                              100%  170KB 170.0KB/s   00:00    
./.lesshst
./.viminfo
./scpplus
./.config/xfce4/desktop/icons.screen0-1350x650.rc
./.xsession-errors
./.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml
./.config/pulse/7f14833c645d4a6abb0beba68b79e0c0-default-source
./.config/pulse/7f14833c645d4a6abb0beba68b79e0c0-default-sink
./.cache/imsettings/log
./.cache/gpg-agent-info
./.ICEauthority
./.vboxclient-draganddrop.pid
./.vboxclient-seamless.pid
./.vboxclient-display.pid
./.vboxclient-clipboard.pid
./.dbus/session-bus/7f14833c645d4a6abb0beba68b79e0c0-0
./.cache/xscreensaver/xscreensaver-getimage.cache
./.config/xfce4/desktop/icons.screen0-1264x950.rc
./work/fpart-0.9.2/src/fpart

最大の問題は、このソリューションがメインサーバーから最新の10gigデータを転送する前にバックアップフォルダを削除することです。最新のデータセットとバックアップデータセットに共通のファイル/ディレクトリが多い場合、効率はそれほど高くありません。しかし、これは実際のデータの最新の10gig(または何でも)を実際に追跡する非常に簡単な方法です(高速で汚れています)。

update2:退屈ですが、2番目の解決策を説明します。

最後に2番目の解決策を見つけました。それではこれについて説明します。コーディングにはあまり効率的ではありません。シェルスクリプトでフォーマットでき、エラーが発生したり、奇妙な形式のファイル名がある場合は、基本的なチェックを実行する大規模なオンラインプログラムです。

最初のソリューションの最大の問題は、常に最新のファイルの最後の10 GBをバックアップしようとしていることです。バックアップされた内容です。つまり、新しい起動時に新しいファイルが1億個しかない場合は、フルバックアップを消去して10Gデータを再送信します(最新の100M、新しい9.9G未満)。

これは一行です。 ssh -n prd 'cd /var/tmp/test/ && find . -type f -printf "%T@ %p %s\n" ' |awk '{ print int($1)" "$2" "$3 }'|sort -n -r >/tmp/remote ; find . -type f -printf "%T@ %p %s\n" |awk '{ print int($1)" "$2" "$3 }'|sort -n -r | awk '{ i+=$3; if (i<=200000) {print $1" "$2" "$3}}'>/tmp/locale; grep -F -x -v -f /tmp/remote /tmp/locale |cut -d" " -f2 >/tmp/newfile;grep -F -x -v -f /tmp/locale /tmp/remote |cut -d" " -f2 >/tmp/toremove; cat /tmp/toremove |while read i; do echo "removing $i on remote server"; ssh -n prd "rm /var/tmp/test/$i"; done ; cat /tmp/newfile | tar -cvf toto.tar -T -&& scp toto.tar prd:/var/tmp/test/ && ssh -n prd "cd /var/tmp/test; tar xvf /var/tmp/test/toto.tar; rm /var/tmp/test/toto.tar"; rm /tmp/remote /tmp/locale /tmp/toremove /tmp/newfile toto.tar

もちろん、prdすべてのディレクトリパス(一時ファイル生成を除く)は、ローカル/リモートサーバーだけでなくサーバーBでも変更されます。ファイル名内にスペースや特殊文字を含むファイル名を処理しないように注意してください。

説明する:

主なアイデアは、バックアップされていないバックアップサーバーの最新のファイルが何であるかを把握することです。バックアップサーバーから古いファイルを消去し、サイズ制限を念頭に置いて、存在しない最新のファイルのみをバックアップサーバーに転送してください。

  • まず、バックアップサーバーに接続してバックアップファイルのリストを取得します。 ;小数部を常にに設定するssh -n prd 'cd /var/tmp/test/ && find . -type f -printf "%T@ %p %s\n" ' |awk '{ print int($1)" "$2" "$3 }'|sort -n -r >/tmp/remote ;問題のため、時々小数部を削除する必要があります。これは、バックアップサーバーとソースサーバーの日付が小数点以下であることを意味します。ソートは、最初のフィールドの最大値から最も低い値で構成されます。つまり、最新のファイルから最も古いファイルの順にソートされます。結果をファイルとして保存します。以前のバックアップでは常に10G未満で転送されたため、全体のサイズを確認する必要はありません。tar0/tmp/remote
  • 次に、全体のサイズが制限より小さい最新のファイルのリストを取得するために、ローカルで同じことを行います。find . -type f -printf "%T@ %p %s\n" |awk '{ print int($1)" "$2" "$3 }'|sort -n -r | awk '{ i+=$3; if (i<=200000) {print $1" "$2" "$3}}'>/tmp/locale;結果を次の場所に保存します。/tmp/locale

したがって、実際に/tmp/locale存在または存在しないすべてのファイルは、同期する/tmp/remoteバックアップサーバーの最新のファイルです。その内外のすべてのファイルは、
削除するバックアップサーバーのファイルです(古いファイル)。/tmp/remote/tmp/locale

これらのサブセットを区別するには、次のものを使用しますgrep

  • grep -F -x -v -f /tmp/remote /tmp/locale |cut -d" " -f2>/tmp/newfile;保存した埋め込み/tmp/localeファイルと含まれていないファイルの両方が表示されます。/tmp/remote/tmp/newfile
  • grep -F -x -v -f /tmp/locale /tmp/remote |cut -d" " -f2 >/tmp/toremove;/tmp/remote含まれているファイルと含まれていないすべてのファイルが表示されます/tmp/locale/tmp/toremove

ディレクトリ構造を維持しながら、リモートで削除するファイルのリストとバックアップサーバーに転送するファイルのリストが作成されました。

tarビルドロケールアーカイブを使用してバックアップを送信し、古いファイルをリモートで削除し、アーカイブを転送し、解凍します。

そして私たちはほぼ終わりました。/tmpクリーンアップのために一時ファイルを削除します。

詳細は次のとおりです。 cat /tmp/toremove |while read i; do echo "removing $i on remote server"; ssh -n prd "rm /var/tmp/test/$i"; done ; このループはiファイルのリストを入力として読み込み、削除したファイルを知らせる小さなメッセージを表示し、次からcatリモートを起動します。rmssh

cat /tmp/newfile | tar -cvf toto.tar -T -&& scp toto.tar prd:/var/tmp/test/ && ssh -n prd "cd /var/tmp/test; tar xvf /var/tmp/test/toto.tar; rm /var/tmp/test/toto.tar";にリストされているすべてのファイルを含むロケールtoto.tarアーカイブが作成されます/tmp/newfile。成功したら、リモートサーバーに送信し、リモートで解凍し、次のブートを妨げsshないようにバックアップサーバーのアーカイブも削除します。

rm /tmp/remote /tmp/locale /tmp/toremove /tmp/newfile toto.tarこの起動時に使用されたファイルのローカルクリーンアップ。

このオンラインプログラムは一時ファイルの使用を排除し、出力をgrepループwhiletarコマンドに直接パイプすることで短縮できます。

scpまた、すべてのコマンドの戻り状態(アーカイブを構築するのに十分な場所ではないか、sshエラー...)と奇妙なファイル名(パラメータ拡張の混乱を避けるためにスペースや特殊文字を含む)を処理するように改善することもできます。

答え2

最近同様の問題が発生しました。私が終わったのはfind + rsyncでした。

#!/usr/bin/env bash
# first prepare the file list I want to sync

find /path -mtime 7 -other-conditions-you-want > /tmp/file.list.$$
rsync --file-from=/tmp/file.list.$$ /source /dest

もちろん、ファイルがリモートサーバーにある場合は、リモートで検索を実行し、 --file-from=:/tmp/file.list.$$ を使用して、次のようにリモートからファイルのリストを取得する必要があります。

ssh "$_SOURCE_HOST" "cd '$_SOURCE_PATH'; find . $MMIN_FLAG -type f > /tmp/$_NAME-$TOKEN"
rsync "--files-from=:/tmp/$_NAME-$TOKEN" "$_SOURCE" "$_DEST"    
ssh "$_SOURCE_HOST" "rm -f /tmp/$_NAME-$TOKEN"

bashのようにrmコマンドを設定して、trapファイルを最後に削除することができます。

関連情報