使用特定方案重命名文件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用特定方案重命名文件相关的知识,希望对你有一定的参考价值。
我有一个FTP文件夹从远程摄像头接收文件。相机将视频文件名始终存储为./rec_YYYY-MM-DD_HH-MM.mkv
。视频文件全部存储在同一文件夹中,即FTP服务器的根文件夹。
我需要使用这个新方案将这些文件移动到另一个文件夹:
- 从文件名中删除
rec_
。 - 将日期格式更改为
DD-MM-YY
。 - 从文件名中删除日期并将其设置为文件夹,其中将存储相同文件和同一日期中的所有其他文件。
- 最终文件路径为:
./DD-MM-YYYY/HH-MM.mkv
。 - 该过程将继续到所有文件,将它们放在与创建日期对应的文件夹中。
总结:./rec_YYYY-MM-DD_HH-MM.mkv
>> ./DD-MM-YYYY/HH-MM.mkv
。这同样适用于同一文件夹中的所有文件。
由于我不能直接从相机发生,这需要在接收文件的服务器上使用Bash完成。
到目前为止,我得到的是脚本,它将获取文件的创建日期并使用它来创建文件夹,然后根据它的创建时间获得创建时间以使用新名称移动文件:
for f in *.mp4
do
mkdir "$f" "$(date -r "$f" +"%d-%m-%Y")"
mv -n "$f" "$(date -r "$f" +"%d-%m-%Y/%H-%M-%S").mp4"
done
我得到这个输出(使用testfile 1.mp4
):
- 它根据文件的创建日期创建文件夹;
- 它将文件重命名为它的创建时间;
- 然后,它返回
mkdir: cannot create directory ‘1.mp4’: File exists
- 如果有两个或多个文件,则只有一个文件被重命名并按照描述移动。其他人保持不变,终点归来:
mkdir: cannot create directory ‘1.mp4’: File exists
mkdir: cannot create directory ‘2.mp4’: File exists
mkdir: cannot create directory ‘12-12-2018’: File exists
有人可以帮帮我吗?更好的建议?谢谢!
老实说,我只会使用Perl或Python。以下是嵌入shell脚本的方法。
这是一个不使用任何库的perl脚本,甚至是随Perl一起提供的库(所以它在没有额外的软件包的情况下工作,如CentOS这样的发行版没有整个Perl库)。 perl脚本为每个文件启动一个新进程以执行复制。
perl -e '
while (<"*.m{p4,kv}">) {
my $path = $_;
my ($prefix, $year, $month, $day, $hour, $minute, $ext) =
split /[.-_]/, $path;
my $sec = q[00];
die "unexpected prefix ($prefix) in $path"
unless $prefix eq q[rec];
die "unexpected extension ($ext) in $path"
unless $ext eq q[mp4] or $ext eq q[mkv];
my $dir = "$day-$month-$year";
my $name = "$hour-$min-$sec" . q[.] . $ext;
my $destpath = $dir . q[/] . $name;
die "$dir . $name is unexpectedly a directory" if (-d $dir);
system("cp", "--", $path, $destpath);
}
'
这是一个Python示例,它与Python 2或Python 3兼容,但确实使用标准库。 Python脚本不会产生任何其他进程。
python3 -c '
import os.path as path
import re
from glob import iglob
from itertools import chain
from os import mkdir
from shutil import copyfile
for p in chain(iglob("*.mp4"), iglob("*.mkv")):
fields = re.split("[-]|[._]", p)
prefix = fields[0]
year = fields[1]
month = fields[2]
day = fields[3]
hour = fields[4]
minute = fields[5]
ext = fields[6]
sec = "00"
assert prefix == "rec"
assert ext in ["mp4", "mkv"]
directory = "".join([day, "-", month, "-", year])
name = "".join([hour, "-", minute, "-", sec, ".", ext])
destpath = "".join([directory, "/", name])
assert not path.isdir(destpath)
try:
mkdir(directory)
except FileExistsError:
pass
copyfile(src=p, dst=destpath)
'
最后,这是一个bash解决方案。它使用-
,.
和_
分割路径,然后通过索引到函数内的$@
来提取各个子字段。索引技巧是可移植的,尽管变量上的正则表达式替换是bash扩展。
#!/bin/bash
# $1 $2 $3 $4 $5 $6 $7 $8
# path rec YY MM DD HH MM ext
process_file() {
mkdir "$5-$4-$3" &> /dev/null
cp -- "$1" "$5-$4-$3"/"$6-$7-00.$8"
}
for path in *.m{p4,kv}; do
[ -e "$path" ] || continue
# NOTE: two slashes are needed in the substitution to replace everything
# read -a ARRAYVAR <<< ... reads the words of a string into an array
IFS=' ' read -a f <<< "${path//[-_.]/ }"
process_file "$path" "${f[@]}"
done
如果你cd /to/some/directory/containing_your_files
然后你可以使用以下脚本
#!/usr/bin/env bash
for f in rec_????-??-??_??-??.m{p4,kv} ; do
dir=${f:4:10} # skip 4 chars ('rec_') take 10 chars ('YYYY_MM_DD')
fnm=${f:15} # skip 15 chars, take the remainder
test -d "$dir" || mkdir "$dir"
mv "$f" "$dir"/"$fnm"
done
注意①我没有交换年份和日期,如果你绝对需要进行交换,你可以提取这样的年份,year=${dir::4}
等,②这种参数替换方法是Bash-ism,例如,它没有在dash
工作。
#!/bin/bash
USER_HOME=$(getent passwd $SUDO_USER | cut -d: -f6)
fn_1 () {
for f in $USER_HOME/FTP/*.mkv
do
mv $f `echo $f | cut -c 29-`
done
}
fn_2 () {
for x in $USER_HOME/FTP/*.mkv
do
mkdir -p "$(date -r "$x" +"$USER_HOME/FTP/Camera1/%d-%m-%Y")"
mv -n "$x" "$(date -r "$x" +"$USER_HOME/FTP/Camera1/%d-%m-%Y/")"
done
}
fn_1
fn_2
我已经到了这个地步。它似乎工作,但我仍然得到不好的输出:
date: '/home/pi/FTP/*.mkv': No such file or directory
mkdir: cannot create directory ‘’: No such file or directory
date: '/home/pi/FTP/*.mkv': No such file or directory
mv: cannot stat '/home/pi/FTP/*.mkv': No such file or directory
如果我回应命令,这就是我得到的:
建议?
你的问题是:mkdir创建文件夹,但你给文件夹创建文件名。
如果要使用fileName创建文件夹,请在不使用扩展名的情况下使用它。
问题是您正在尝试使用现有的fileName创建文件夹
以上是关于使用特定方案重命名文件的主要内容,如果未能解决你的问题,请参考以下文章