基本上我的硬盘崩溃了,我能够恢复所有文件,但是,所有的文件都保留了他们的元和文件。有些人保留了他们的名字,我有274000张图片,我需要或多或少,按日期排序到文件夹中。
所以,让我们说它从第一个文件开始,它将从文件中获取日期,创建一个子文件夹,直到日期更改,一旦日期更改,继续将该文件移动到创建的文件夹中,它会创建一个新的文件夹并继续做同样的事情。
我确定这是可能的,我真的不想手动这样做,因为这需要几个星期......
假设我有一个目标文件夹/ target /
目标包含274000个文件,根本没有子文件夹。
文件夹结构应为 / target / YY / DD_MM / filenames
我想为此创建一个bash脚本,但我不确定从哪里开始。
我发现了这个:
#!/bin/bash
DIR=/home/data
target=$DIR
cd "$DIR"
for file in *; do
dname="$( date -d "${file%-*}" "+$target/%Y/%b_%m" )"
mkdir -vp "${dname%/*}"
mv -vt "$dname" "$file"
done
创建文件夹而不检查它是否存在删除该文件夹中的文件?
我还不太清楚在dir路径名中添加asterix会有什么用呢?
我对bash不太熟悉,但如果有人可以向我解释一下发生了什么事情,我很乐意让这个工作起作用吗?
三江源!
答案 0 :(得分:3)
我似乎找到了一个适合我的答案,这个在OSX上工作得很好,在我在大量文件夹上运行它之前,你们可以检查一下这不会在某个地方失败吗?
#!/bin/bash
DIR=/Users/limeworks/Downloads/target
target=$DIR
cd "$DIR"
for file in *; do
# Top tear folder name
year=$(stat -f "%Sm" -t "%Y" $file)
# Secondary folder name
subfolderName=$(stat -f "%Sm" -t "%d-%m-%Y" $file)
if [ ! -d "$target/$year" ]; then
mkdir "$target/$year"
echo "starting new year: $year"
fi
if [ ! -d "$target/$year/$subfolderName" ]; then
mkdir "$target/$year/$subfolderName"
echo "starting new day & month folder: $subfolderName"
fi
echo "moving file $file"
mv "$file" "$target/$year/$subfolderName"
done
答案 1 :(得分:2)
我的其他解决方案的性能存在问题,因为我的文件系统是远程挂载的,访问时间很长。
我在bash和python中使用了一些改进的解决方案:
Bash版本:
record # cat test.sh
for each in *.mkv
do
date=$(date +%Y-%d-%m -r "$each");
_DATES+=($date);
FILES+=($each);
done
DATES=$(printf "%s\n" "${_DATES[@]}" | sort -u);
for date in ${DATES[@]}; do
if [ ! -d "$date" ]; then
mkdir "$date"
fi
done
for i in ${FILES[@]}; do
dest=$(date +%Y-%d-%m -r "$i")
mv $i $dest/$i
done
record # time bash test.sh
real 0m3.785s
record #
import os, datetime, errno, argparse, sys
def create_file_list(CWD):
""" takes string as path, returns tuple(files,date) """
files_with_mtime = []
for filename in [f for f in os.listdir(CWD) if os.path.splitext(f)[1] in ext]:
files_with_mtime.append((filename,datetime.datetime.fromtimestamp(os.stat(filename).st_mtime).strftime('%Y-%m-%d')))
return files_with_mtime
def create_directories(files):
""" takes tuple(file,date) from create_file_list() """
m = []
for i in files:
m.append(i[1])
for i in set(m):
try:
os.makedirs(os.path.join(CWD,i))
except OSError as exception:
if exception.errno != errno.EEXIST:
raise
def move_files_to_folders(files):
""" gets tuple(file,date) from create_file_list() """
for i in files:
try:
os.rename(os.path.join(CWD,i[0]), os.path.join(CWD,(i[1] + '/' + i[0])))
except Exception as e:
raise
return len(files)
if __name__ == '__main__':
parser = argparse.ArgumentParser(prog=sys.argv[0], usage='%(prog)s [options]')
parser.add_argument("-e","--extension",action='append',help="File extensions to match",required=True)
args = parser.parse_args()
ext = ['.' + e for e in args.extension]
print "Moving files with extensions:", ext
CWD = os.getcwd()
files = create_file_list(CWD)
create_directories(files)
print "Moved %i files" % move_files_to_folders(files)
record # time python sort.py -e mkv
Moving files with extensions: ['.mkv']
Moved 319 files
real 0m1.543s
record #
这两个脚本都是在过去3天内修改的319个mkv文件上进行测试的。
答案 2 :(得分:1)
我在一个小脚本上工作并测试过它。希望这有帮助。
#!/bin/bash
pwd=`pwd`
#list all files,cut date, remove duplicate, already sorted by ls.
dates=`ls -l --time-style=long-iso|grep -e '^-.*'|awk '{print $6}'|uniq`
#for loop to find all files modified on each unique date and copy them to your pwd
for date in $dates; do
if [ ! -d "$date" ]; then
mkdir "$date"
fi
#find command will find all files modified at particular dates and ignore hidden files.
forward_date=`date -d "$date + 1 day" +%F`
find "$pwd" -maxdepth 1 -not -path '*/\.*' -type f -newermt "$date" ! -newermt "$forward_date" -exec cp -f {} "$pwd/$date" \;
done
您必须在工作目录中,根据日期存在要复制的文件。