将平面文件系统移动、重命名为基于文件名的目录
Move, Rename Flat File System to directories based on filename
我有一个 sun 目录挂载在 centos 系统上,有 16000+ movs,写入它们的应用程序现在由于文件量而难以读取目录。
每个文件名都是唯一的,并由破折号 (-) 分隔,如果没有破折号,则保留在根目录中。
例如。
文件名 02342.mov、1-9593-0002-001.mov、1-9593-0002-002.mov、2-3690-0005-001.mov、Y- 0757-0245.mov 和 ROB-01-002-Y.mov 应该像这样结束,以便客户端的网络流媒体应用程序可以将其作为原始文件名进行流式传输(他们的网络团队将处理该部分)。
mnt
|-- media
|-- 02342.mov
|-- 1
| |-- 9593
| |-- 0002
| |-- 001.mov
| |-- 002.mov
|-- 2
| |-- 3690
| |-- 0005
| |-- 001.mov
|-- ROB
| |-- 01
| |-- 002
| |-- Y.mov
|-- Y
|-- 0757
|-- 0245.mov
但是它将最后一部分创建为目录,例如/mnt/media/1/9593/0002/001.mov/
到目前为止我的 被盗 脚本。
#!/bin/sh
for i in $(/bin/ls *-* | xargs)
do
dir=$(echo $i | cut -f1 -d '-')
mkdir -p $dir
dir1=$(echo $i | cut -f2 -d '-')
mkdir -p $dir/$dir1
dir2=$(echo $i | cut -f3 -d '-')
mkdir -p $dir/$dir1/$dir2
dir3=$(echo $i | cut -f4 -d '-') #here is where I get lost
mkdir -p $dir/$dir1/$dir2/$dir3
#dir4=$(echo $i | cut -f5 -d '-')
#mkdir -p $dir/$dir1/$dir2/$dir3/$dir4
echo $dir3
#mv $i $dir3 # This doesnt work.
done
我很确定只执行 dir1、dir2 等等是错误的方法,但我目前的知识有限。
最后一部分我打算在之后做一个简单的正则表达式重命名,但还没到那一步。
D
我先提供一个伪算法
- 使用
find
查找所有mov文件
每个文件名
2.1 trim 文件名路径及其结尾使用 bash 替换
like `${filename##*/}` and `${filename%-*\.mov}`
2.2 使用 bash 的替换内置
替换所有破折号
like `${filename//-/\/}`
2.3 mkdir -p ${filename//-/\/}
2.4 根据需要移动文件
希望这有助于构建脚本。
无需调用 ls
、xargs
或 cut
。 Bash可以通过路径扩展和参数扩展来处理
for mov in *-*.mov ; do
path=${mov//-//} # Replace all "-" with "/"
path=${path%/*} # Remove from the last "/"
mkdir -p "$path"
name=${mov##*-} # Remove up to the last "-"
mv "$mov" "$path/$name"
done
glob 可能需要很长时间,甚至会失败。最好使用一种可以逐个读取文件而无需列出所有文件的工具。参见 Perl to the rescue: case study of deleting a large directory。
我有一个 sun 目录挂载在 centos 系统上,有 16000+ movs,写入它们的应用程序现在由于文件量而难以读取目录。
每个文件名都是唯一的,并由破折号 (-) 分隔,如果没有破折号,则保留在根目录中。 例如。
文件名 02342.mov、1-9593-0002-001.mov、1-9593-0002-002.mov、2-3690-0005-001.mov、Y- 0757-0245.mov 和 ROB-01-002-Y.mov 应该像这样结束,以便客户端的网络流媒体应用程序可以将其作为原始文件名进行流式传输(他们的网络团队将处理该部分)。
mnt
|-- media
|-- 02342.mov
|-- 1
| |-- 9593
| |-- 0002
| |-- 001.mov
| |-- 002.mov
|-- 2
| |-- 3690
| |-- 0005
| |-- 001.mov
|-- ROB
| |-- 01
| |-- 002
| |-- Y.mov
|-- Y
|-- 0757
|-- 0245.mov
但是它将最后一部分创建为目录,例如/mnt/media/1/9593/0002/001.mov/
到目前为止我的 被盗 脚本。
#!/bin/sh
for i in $(/bin/ls *-* | xargs)
do
dir=$(echo $i | cut -f1 -d '-')
mkdir -p $dir
dir1=$(echo $i | cut -f2 -d '-')
mkdir -p $dir/$dir1
dir2=$(echo $i | cut -f3 -d '-')
mkdir -p $dir/$dir1/$dir2
dir3=$(echo $i | cut -f4 -d '-') #here is where I get lost
mkdir -p $dir/$dir1/$dir2/$dir3
#dir4=$(echo $i | cut -f5 -d '-')
#mkdir -p $dir/$dir1/$dir2/$dir3/$dir4
echo $dir3
#mv $i $dir3 # This doesnt work.
done
我很确定只执行 dir1、dir2 等等是错误的方法,但我目前的知识有限。
最后一部分我打算在之后做一个简单的正则表达式重命名,但还没到那一步。
D
我先提供一个伪算法
- 使用
find
查找所有mov文件
每个文件名
2.1 trim 文件名路径及其结尾使用 bash 替换
like `${filename##*/}` and `${filename%-*\.mov}`
2.2 使用 bash 的替换内置
替换所有破折号like `${filename//-/\/}`
2.3 mkdir -p
${filename//-/\/}
2.4 根据需要移动文件
希望这有助于构建脚本。
无需调用 ls
、xargs
或 cut
。 Bash可以通过路径扩展和参数扩展来处理
for mov in *-*.mov ; do
path=${mov//-//} # Replace all "-" with "/"
path=${path%/*} # Remove from the last "/"
mkdir -p "$path"
name=${mov##*-} # Remove up to the last "-"
mv "$mov" "$path/$name"
done
glob 可能需要很长时间,甚至会失败。最好使用一种可以逐个读取文件而无需列出所有文件的工具。参见 Perl to the rescue: case study of deleting a large directory。