已解决:请参阅评论中的更新。
我正在尝试根据该日期将文件名中带有日期的文件排序到文件夹中。这些文件的文件名中曾经有一个空格,如下所示。有一些旧文件,所以我也需要对它们进行排序。
调度传真_20180521121901.pdf
我们现在获取的文件名中没有空格,因此它只是 Dispatch_20180521124202.pdf
日期是 20180521,其余部分我认为是消息 ID,但我们不需要它。只是日期。
这次尝试使用 bash 脚本(ubuntu 18.04 盒子)最终创建了一个名为 2018-05-21 的文件夹,该文件夹位于文件所在目录的上一级目录,并将所有 pdf 文件放入该文件夹中。
for x in /home/tb/temp/*.pdf
do
d=$(date -r "$x" +%Y-%m-%d)
mkdir -p "$d"
mv -- "$x" "$d/"
done
这最终以某种方式进入了一个名为“e”的文件夹。
for x in /home/tb/temp/*.pdf
do
d="${x:4:4}-${x:8:2}-${x:10:2}"
mkdir -p "$d"
mv -- "$x" "$d/"
done
这次尝试?我最终为每个 PDF 建立了一个文件夹。
/home/tb/20180521124202.pdf/Dispatch Fax_20180521124202.pdf /home/tb/20180521121901.pdf/Dispatch Fax_20180521121901.pdf
for x in /home/tb/temp/*.pdf
do
d=$(echo "$x" | awk -F _ '{print $2}')
mkdir -p "$d"
mv -- "$x" "$d/"
done
脚本来自之前的帖子这里和这里这些对他们有用,但即使目标是相同的,我也没有同样的运气。
我的目标是最终从 rsync 填充临时目录(从另一台服务器提取这些文件),然后通过 cron,运行此脚本以根据日期将内容移动到文件夹中,并通过启用“选项+索引”的 Apache 提供该目录。这是一个仅限 Intranet 的页面,并且该特定计算机无法从外部访问。目录结构很简单。最终类似 /var/www/html/2018/5/21 等,遵循 YYYY/MM/DD 格式。
我只是不知道如何让它工作,而且我对 bash 脚本的了解非常生疏。我看过其他几个例子,比如这个但后来我发现它不适用于文件名中包含空格的文件。
我对想法持开放态度!
答案1
你的问题对我来说并不完全清楚,但我想我可能明白你想做什么。
这是您正在使用的循环:
for x in /home/tb/temp/*.pdf
do
d="${x:4:4}-${x:8:2}-${x:10:2}"
mkdir -p "$d"
mv -- "$x" "$d/"
done
您给出的示例文件名是:
Dispatch Fax_20180521121901.pdf
Dispatch_20180521124202.pdf
我突然想到的一个问题是你的参数替换表达式 ( d="${x:4:4}-${x:8:2}-${x:10:2}"
) 似乎没有产生正确的结果,例如:
> x='Dispatch Fax_20180521121901.pdf'
> d="${x:4:4}-${x:8:2}-${x:10:2}"
> echo ${d}
atch- F-ax
> x='Dispatch_20180521124202.pdf'
> d="${x:4:4}-${x:8:2}-${x:10:2}"
> echo ${d}
atch-_2-01
您可以尝试使用grep
代替,例如:
> x='Dispatch Fax_20180521121901.pdf'
> d=$(echo "${x}" | grep -Po '\d{8}')
> echo ${d}
20180521
> x='Dispatch Fax_20180521121901.pdf'
> d=$(echo "${x}" | grep -Po '\d{8}')
> echo ${d}
20180521
或者,如果您想添加连字符,您可以使用以下sed
基于命令替换:
> x='Dispatch Fax_20180521121901.pdf'
> d=$(echo "${x}" | sed -E 's/^[^0-9]*([0-9]{4})([0-9]{2})([0-9]{2}).*$/\1-\2-\3/')
> echo ${d}
2018-05-21
> x='Dispatch Fax_20180521121901.pdf'
> d=$(echo "${x}" | sed -E 's/^[^0-9]*([0-9]{4})([0-9]{2})([0-9]{2}).*$/\1-\2-\3/')
> echo ${d}
2018-05-21
假设这是所需的结果(即您需要 形式的子目录%Y-%m-%d
),我们可以将您的参数替换表达式替换为grep
基于 - 的命令替换。这将为我们提供以下修改后的循环:
for filename in /home/tb/temp/*.pdf; do
datestring=$(echo "${filename}" | sed -E 's/^[^0-9]*([0-9]{4})([0-9]{2})([0-9]{2}).*$/\1-\2-\3/')
mkdir -p "${datestring}"
mv -i -- "${filename}" "${datestring}/"
done
这应该会生成表单的子目录%Y-%m-%d
并用适当的文件填充它们。
更新:根据您的评论,听起来您想要的是 form 的嵌套子目录%Y/%m/%d
。为此,您需要分别提取年、月和日子字符串,例如:
> x='Dispatch Fax_20180521121901.pdf'
> d=$(echo "${x}" | grep -Po '\d{8}')
> year=${d:0:4}
> month=${d:4:2}
> day=${d:6:2}
> echo "${year}/${month}/${day}/"
2018/05/21/
这导致我们进入以下循环:
for filename in /home/tb/temp/*.pdf; do
datestring=$(echo "${filename}" | grep -Po '\d{8}')
year=${datestring:0:4}
month=${datestring:4:2}
day=${datestring:6:2}
directory="${year}/${month}/${day}/"
mkdir -p "${directory}"
mv -i -- "${filename}" "${directory}"
done
答案2
如果您不必处理积极敌对的文件名,
sed -E 's/([0-9]{0,7}[^0-9]+)*([0-9]{8}).*/mkdir -p \2; mv "&" \2/e'
# 111111111111111111 2222222222
该模式是 0 到 7 位数字,后跟一些非数字,任意次数,后跟 8 位数字,一次。第二个模式是 8 位数字,与日期匹配。
如果您没有 GNU sed,您可以代替标志e
将结果通过管道传输到 shell 中。