我想将所有超过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下面的文件树。我认为这应该可以通过简单地用另一种方式替换字符串,但是如何?用于此目的的命令是什么?
谢谢!
答案 0 :(得分:3)
我会采用这条路线而不是rsync
:
更改目录,以便我们可以处理相对路径名而不是绝对路径名:
cd /home/user/documents
运行find
命令并将输出提供给cpio
,请求它为文件建立硬链接(-l
),创建主要目录({{ 1}})并保留属性(-d
)。 -m
和-print0
选项使用空值作为记录终止符来正确处理其中包含空格的文件名。 -0
的{{1}}选项使用链接而不是实际复制文件,因此使用的空间非常少(只是新目录所需的空间)。
-l
重新运行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