仅存档旧文件并在存档中重新构建文件夹树

时间:2013-09-05 15:40:43

标签: linux bash copy find backup

我想将所有超过1000天的文件从/ home / user / documents移动到/ home / user / archive中,这些文件分布在各种子文件夹中。我试过的命令是

find /home/user/documents -type f -mtime +1000 -exec rsync -a --progress --remove-source-files {} /home/user/archive \;

问题是,(可以理解)所有文件最终都被移动到单个文件夹/ home / user / archive中。但是,我想要的是重新构建/ home / user / archive中/ home / user / documents下面的文件树。我认为这应该可以通过简单地用另一种方式替换字符串,但是如何?用于此目的的命令是什么?

谢谢!

2 个答案:

答案 0 :(得分:3)

我会采用这条路线而不是rsync

  1. 更改目录,以便我们可以处理相对路径名而不是绝对路径名:

    cd /home/user/documents
    
  2. 运行find命令并将输出提供给cpio,请求它为文件建立硬链接(-l),创建主要目录({{ 1}})并保留属性(-d)。 -m-print0选项使用空值作为记录终止符来正确处理其中包含空格的文件名。 -0的{​​{1}}选项使用链接而不是实际复制文件,因此使用的空间非常少(只是新目录所需的空间)。

    -l
  3. 重新运行cpio命令并将输出反馈到find . -type f -mtime +1000 -print0 | cpio -dumpl0 /home/user/archives 以删除原件:

    find

答案 1 :(得分:0)

这也是一个脚本。

#!/bin/bash

[ -n "$BASH_VERSION" ] && [[ BASH_VERSINFO -ge 4 ]] || {
    echo "You need Bash version 4.0 to run this script."
    exit 1
}

# SOURCE=/home/user/documents/
# DEST=/home/user/archive/

SOURCE=$1
DEST=$2

declare -i DAYSOLD=10
declare -a DIRS=()
declare -A DIRS_HASH=()
declare -a FILES=()
declare -i E=0

# Check directories.

[[ -n $SOURCE && -d $SOURCE && -n $DEST && -d $DEST ]] || {
    echo "Source or destination directory may be invalid."
    exit 1
}

# Format source and dest variables properly:

SOURCE=${SOURCE%/}
DEST=${DEST%/}
SOURCE_LENGTH=${#SOURCE}

# Copy directories first.

echo "Creating directories."

while read -r FILE; do
    DIR=${FILE%/*}
    if [[ -z ${DIRS_HASH[$DIR]} ]]; then
        PARTIAL=${DIR:SOURCE_LENGTH}
        if [[ -n $PARTIAL ]]; then
            TARGET=${DEST}${PARTIAL}
            echo "'$TARGET'"
            mkdir -p "$TARGET" || (( E += $? ))
            chmod --reference="$DIR" "$TARGET" || (( E += $? ))
            chown --reference="$DIR" "$TARGET" || (( E += $? ))
            touch --reference="$DIR" "$TARGET" || (( E += $? ))
            DIRS+=("$DIR")
        fi
        DIRS_HASH[$DIR]=.
    fi
done < <(exec find "$SOURCE" -mindepth 1 -type f -mtime +"$DAYSOLD")

# Copy files.

echo "Copying files."

while read -r FILE; do
    PARTIAL=${FILE:SOURCE_LENGTH}
    cp -av "$FILE" "${DEST}${PARTIAL}" || (( E += $? ))
    FILES+=("$FILE")
done < <(exec find "$SOURCE" -mindepth 1 -type f -mtime +"$DAYSOLD")

# Remove old files.

if [[ E -eq 0 ]]; then
    echo "Removing old files."
    rm -fr "${DIRS[@]}" "${FILES[@]}"
else
    echo "An error occurred during copy. Not removing old files."
    exit 1
fi