Encryption 批量重命名/移动/散列文件
我有一个高度结构化的分层目录,其中包含多个文件,这些文件需要移动到平面结构中,并同时重命名。原始路径和名称必须与新路径和名称一起记录,并最终加载到数据库中。最后,每个重命名的文件必须获得唯一的、不可使用的(即:加密或哈希)文件名。当重命名的文件被移动到新的目录结构中时,我还想限制每个目录中文件的数量,这样每个目录都会创建一个序号作为其名称,然后将文件加载到其中,直到达到最大文件数(例如:255)在滚动到名称为下一个序列号的新目录之前 是否有这样的工具/软件?我做了一些初步研究,没有得出以下标准:Encryption 批量重命名/移动/散列文件,encryption,filenames,batch-processing,batch-rename,Encryption,Filenames,Batch Processing,Batch Rename,我有一个高度结构化的分层目录,其中包含多个文件,这些文件需要移动到平面结构中,并同时重命名。原始路径和名称必须与新路径和名称一起记录,并最终加载到数据库中。最后,每个重命名的文件必须获得唯一的、不可使用的(即:加密或哈希)文件名。当重命名的文件被移动到新的目录结构中时,我还想限制每个目录中文件的数量,这样每个目录都会创建一个序号作为其名称,然后将文件加载到其中,直到达到最大文件数(例如:255)在滚动到名称为下一个序列号的新目录之前 是否有这样的工具/软件?我做了一些初步研究,没有得出以下标准:
- 批量重命名并复制到备选(更平坦)结构中
- 哈希/加密文件名并确保唯一性
- 按顺序命名文件夹并限制文件数
- 记录每个文件的原始名称和路径,以及新的(加密的)名称和路径
#!/bin/bash
MAXFILESPERDIR=500
TARGETROOTDIR="./newrepository"
RANDOMDISTRIBUTION=1
if [ -d "$1" ]; then
LOGFILE=$(basename $0).$(date +"_%Y%m%d_%H%M").${$}.log
SQLFILE=$(basename $0).$(date +"_%Y%m%d_%H%M").${$}.sql
SOURCEDIR="$1"
TOTALSOURCEFILES=$(find "$1" -type f | wc -l)
let "TOTALTARGETDIRS=$TOTALSOURCEFILES / $MAXFILESPERDIR"
PADLENTARGETDIRS=${#TOTALTARGETDIRS}
PADLENTARGETFILE=${#TOTALSOURCEFILES}
echo "We will create $TOTALTARGETDIRS directories to hold $MAXFILESPERDIR files per directory."
if [ "$RANDOMDISTRIBUTION" == "1" ] ; then
echo "We will rename and distribute each file randomly."
else
echo "We will rename and distribute each file uniformly."
fi
echo "Do you want to continue?"
select choice in yes no ; do
if [ "$choice" == "yes" ] ; then
COUNTER=1
find "$1" -type f | while read SOURCEFILE ; do {
CHECKSUMFILE=$(sha1sum "$SOURCEFILE" | cut -d " " -f 1)
CHECKSUMNAME=$(echo "$SOURCEFILE" | sha1sum | cut -d " " -f 1)
DETERMINISTICNONCE=$(printf "%0${PADLENTARGETFILE}d\n" $COUNTER)
if [ "$RANDOMDISTRIBUTION" == "1" ] ; then
PROBABILISTICNONCE=$(let "XX=$RANDOM % $TOTALTARGETDIRS + 1" ; printf "%0${PADLENTARGETDIRS}d\n" $XX;)
else
PROBABILISTICNONCE=$(let "XX=$COUNTER % $TOTALTARGETDIRS + 1" ; printf "%0${PADLENTARGETDIRS}d\n" $XX;)
fi
FILEDATE=$(stat -c %z "$SOURCEFILE" | cut -d "." -f 1)
FILESIZE=$(stat -c %s "$SOURCEFILE")
echo "Source file $SOURCEFILE" >> $LOGFILE
echo "Target file $TARGETROOTDIR/$PROBABILISTICNONCE/$PROBABILISTICNONCE$CHECKSUMFILE$DETERMINISTICNONCE" >> $LOGFILE
echo "INSERT INTO files (Filename, Location, Checksum, CDate, Size) VALUES ('$PROBABILISTICNONCE$CHECKSUMFILE$DETERMINISTICNONCE', '$PROBABILISTICNONCE', '$CHECKSUMFILE', '$FILEDATE', $FILESIZE);" >> $SQLFILE
mkdir -p $TARGETROOTDIR/$PROBABILISTICNONCE
cp -v "$SOURCEFILE" $TARGETROOTDIR/$PROBABILISTICNONCE/$PROBABILISTICNONCE$CHECKSUMFILE$DETERMINISTICNONCE
let "COUNTER+=1"
} ; done
echo "Done."
echo
break
fi
if [ "$choice" == "no" ] ; then
echo
echo "Operation cancelled"
echo
break
fi
done
else
echo
echo "Missing source directory"
echo
fi
只需从新存储库的根目录运行它。您可以通过修改第一个变量对其进行配置:MAXFILESPERDIR定义每个目录要存储的文件数,TargetRotDir是创建第一个级别目录的第一个级别目录的名称(它只使用两个级别,第一个级别实际上是一个根目录),RANDOMDISTRIBUTION定义文件是否随机分布(它可能看起来不均匀,特别是对于小跑步)或决定性(只是计数)
工作原理(仅供参考,以防这不是您想要的,但也许您可以获得一些想法):
- 计算文件内容的SHA1哈希
- 创建一个确定的nonce
- 创建一个概率nonce(如果RANDOMDISTRIBUTION为1,否则仅创建一个计数器)
- 获取尺寸和修改日期
- 将随机值的值与散列和计数器组合,以获得新的文件名(路径将是随机值)
- 记录源和目标完整路径
- 创建并记录SQL插入查询
- 创建目标目录(如果不存在)
- 复制文件。(你可以移动它,如果你想,但我是出于安全考虑)
最后,这是一个一次性迁移脚本,它并不是为了定期在同一组文件上执行而编写的。我有几个Bash脚本,我过去曾使用它们将手工制作的文件存储库迁移到散列存储库,以便从web应用程序(主要是PHP应用程序)访问和管理。在这些存储库中,文件名是散列的(以避免与具有相同内容/名称的文件发生冲突),文件是均匀分布的(以确定的方式或随机的方式),以使每个目录的文件数较低,这是出于性能原因。以下是一个完全有效的示例:
#!/bin/bash
MAXFILESPERDIR=500
TARGETROOTDIR="./newrepository"
RANDOMDISTRIBUTION=1
if [ -d "$1" ]; then
LOGFILE=$(basename $0).$(date +"_%Y%m%d_%H%M").${$}.log
SQLFILE=$(basename $0).$(date +"_%Y%m%d_%H%M").${$}.sql
SOURCEDIR="$1"
TOTALSOURCEFILES=$(find "$1" -type f | wc -l)
let "TOTALTARGETDIRS=$TOTALSOURCEFILES / $MAXFILESPERDIR"
PADLENTARGETDIRS=${#TOTALTARGETDIRS}
PADLENTARGETFILE=${#TOTALSOURCEFILES}
echo "We will create $TOTALTARGETDIRS directories to hold $MAXFILESPERDIR files per directory."
if [ "$RANDOMDISTRIBUTION" == "1" ] ; then
echo "We will rename and distribute each file randomly."
else
echo "We will rename and distribute each file uniformly."
fi
echo "Do you want to continue?"
select choice in yes no ; do
if [ "$choice" == "yes" ] ; then
COUNTER=1
find "$1" -type f | while read SOURCEFILE ; do {
CHECKSUMFILE=$(sha1sum "$SOURCEFILE" | cut -d " " -f 1)
CHECKSUMNAME=$(echo "$SOURCEFILE" | sha1sum | cut -d " " -f 1)
DETERMINISTICNONCE=$(printf "%0${PADLENTARGETFILE}d\n" $COUNTER)
if [ "$RANDOMDISTRIBUTION" == "1" ] ; then
PROBABILISTICNONCE=$(let "XX=$RANDOM % $TOTALTARGETDIRS + 1" ; printf "%0${PADLENTARGETDIRS}d\n" $XX;)
else
PROBABILISTICNONCE=$(let "XX=$COUNTER % $TOTALTARGETDIRS + 1" ; printf "%0${PADLENTARGETDIRS}d\n" $XX;)
fi
FILEDATE=$(stat -c %z "$SOURCEFILE" | cut -d "." -f 1)
FILESIZE=$(stat -c %s "$SOURCEFILE")
echo "Source file $SOURCEFILE" >> $LOGFILE
echo "Target file $TARGETROOTDIR/$PROBABILISTICNONCE/$PROBABILISTICNONCE$CHECKSUMFILE$DETERMINISTICNONCE" >> $LOGFILE
echo "INSERT INTO files (Filename, Location, Checksum, CDate, Size) VALUES ('$PROBABILISTICNONCE$CHECKSUMFILE$DETERMINISTICNONCE', '$PROBABILISTICNONCE', '$CHECKSUMFILE', '$FILEDATE', $FILESIZE);" >> $SQLFILE
mkdir -p $TARGETROOTDIR/$PROBABILISTICNONCE
cp -v "$SOURCEFILE" $TARGETROOTDIR/$PROBABILISTICNONCE/$PROBABILISTICNONCE$CHECKSUMFILE$DETERMINISTICNONCE
let "COUNTER+=1"
} ; done
echo "Done."
echo
break
fi
if [ "$choice" == "no" ] ; then
echo
echo "Operation cancelled"
echo
break
fi
done
else
echo
echo "Missing source directory"
echo
fi
只需从新存储库的根目录运行它。您可以通过修改第一个变量对其进行配置:MAXFILESPERDIR定义每个目录要存储的文件数,targetRotDir是创建第一个级别目录的第一个级别目录的名称(它只使用两个级别,第一个级别实际上是单个根目录),而RANDOMDISTRIBUTION定义了文件是随机分布的(可能看起来不均匀,特别是小规模运行)还是确定性分布的(只是计数)
工作原理(仅供参考,以防这不是您想要的,但也许您可以获得一些想法):
- 计算文件内容的SHA1哈希
- 创建一个确定的nonce
- 创建一个概率nonce(如果RANDOMDISTRIBUTION为1,否则仅创建一个计数器)
- 获取尺寸和修改日期
- 将随机值的值与散列和计数器组合,以获得新的文件名(路径将是随机值)
- 记录源和目标完整路径
- 创建并记录SQL插入查询
- 创建目标目录(如果不存在)
- 复制文件。(你可以移动它,如果你想,但我是出于安全考虑)