0

我想将分布在各个子文件夹中的所有超过 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 下面重新构建文件树。我认为这应该可以通过简单地用另一个字符串替换一个字符串来实现,但是如何呢?服务于这个目的的命令是什么?

谢谢!

4

2 回答 2

3

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

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

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

    find . -type f -mtime +1000 -print0 | cpio -dumpl0 /home/user/archives
    
  3. 重新运行您的find命令并将输出提供xargs rm给以删除原件:

    find . -type f -mtime +1000 -print0 | xargs -0 rm
    
于 2013-09-05T17:59:24.283 回答
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
于 2013-09-05T19:37:55.197 回答