Scripting

rsync 最近的 x GB

  • December 5, 2013

我正在尋找一個命令/腳本,以允許將最近修改的文件(最多)10GB 複製到另一台電腦。

因此,如果有 4 個每個 4 GB 的文件,則腳本只應傳輸其中 2 個,如果有 12 個 1GB 大的文件,則僅應傳輸最近的 10 個。

這是一個腳本,可以滿足您的要求。

要求

  • 傳輸的文件總數必須小於門檻值大小。
  • 與 rsync 目標相比,必須修改文件。
  • 如果不能傳輸所有文件,則必須選擇最近修改的文件。

細節

它用於rsync --dry-run建構將要傳輸的文件列表(這些是修改後的文件)。然後它使用du和的組合ls來獲取文件大小和 mtime。然後它按 mtime 對文件進行排序,然後循環它們直到總大小超過門檻值。最後,它再次呼叫 rsync,僅使用最近修改的文件和總大小低於門檻值的文件。

腳本有點難看,但它可以工作。一個很大的限制是它必須在包含 rsync from-directory 的機器上執行。可以修改它以使用 ssh 來使用遠端源目錄,但該 excersize 留給讀者。

最後,這些rsync選項被硬編碼到腳本中,但如果您想在命令行上指定它們,這很容易更改。此外,計算大小的數學以字節為單位。通過修改對 du 的呼叫並將門檻值降低相同的因子,可以將其更改為千/兆/千兆字節。

用法

./rsyncrecent.sh rsync-from-directory rsync-to-directory

wherersync-from-directory是本地目錄,並且rsync-to-directory是任何本地或遠端目錄。預設選項硬編碼為-avz,預設門檻值硬編碼為10GiB.

劇本

#!/bin/bash

RSYNC=rsync
RSYNC_OPTS=-avz
THRESHOLD=10737418240

usage () {
 echo >&2 "Usage:  $0 from-location to-location"
 exit 1
}

[ "$#" -eq 2 ] || usage

RSYNC_FROM=$1
RSYNC_TO=$2

echo "Fetching file list for $RSYNC $RSYNC_OPTS $RSYNC_FROM $RSYNC_TO"

# get list of changed files
FILES=`$RSYNC $RSYNC_OPTS --dry-run  $RSYNC_FROM $RSYNC_TO | sed -n '/list$/,/^$/{/sending.*list$/ d ; /^$/ d ; /\/$/ d ;; p}'`

# reported files are relative to ..RSYNC_FROM, so rather than transforming filenames, lets just move there
pushd $RSYNC_FROM > /dev/null

# get modified time and sizes for all files
i=0
for FILE in $FILES
do
  #strip first part of path so files are relative to RSYNC_FROM
  FILE=${FILE#*/}
  #FSIZE=`ls -l $FILE | cut -f5 -d' '`
  FSIZE=`du -bs $FILE`
  FMTIME=`ls -l --time-style=+%s $FILE | cut -f6 -d' '`
  FLIST[$i]=`echo $FMTIME $FILE $FSIZE`
  ((i=$i+1))
done

# go back to original directory
popd > /dev/null

# sort list according to modified time
IFS=$'\n' FLIST=($(sort -rg <<<"${FLIST[*]}"))

max=$i
i=0
size=0
#NEWFLIST=''

# add up the files in mtime order until threshold is reached
for ((i=0; i<$max; i++))
do
  s=`echo ${FLIST[$i]} | cut -f3 -d' '`
  f=`echo ${FLIST[$i]} | cut -f2 -d' '`
  ((size=$size+$s))
  if (( "$size" > "$THRESHOLD" ))
  then
     break
  fi
  NEWFLIST="$NEWFLIST $f"
  echo $f >> /tmp/rsyncfilelist
done

$RSYNC $RSYNC_OPTS --dry-run $RSYNC_FROM --files-from=/tmp/rsyncfilelist  $RSYNC_TO

rm /tmp/rsyncfilelist

引用自:https://unix.stackexchange.com/questions/97177