如何用年,月,日的文件夹层次结构替换名称为日期(即YYYYMMDD)的文件夹?


8

我有一个文件夹列表,其中有名称的日期。日期格式为YYYYMMDD(例如20150129)。在这些文件夹中是与该特定日期相关的文本文档。

我想将它们重新组织成一个文件夹结构,从每年的月份到当前的日期,并将文本文档移到层次结构中较低的相应“ date”文件夹中。

换句话说,我希望“ root”文件夹以像2015这样的年份命名,然后创建以诸如01的月份命名的子文件夹,然后创建以诸如29的日期命名的其他子文件夹,其中包含相应的文本文档。 。

所以路径看起来像2015/01/29/file.txt还是2015>01>29>file.txt

我看了一下Automator,虽然我可能错了,但似乎不可能实现这样的事情,所以我想知道...

  1. 是否有任何外行可以理解的简单解决方案,例如Automator工作流程,或者这需要对终端命令和正则表达式有一定了解?

  2. 如果实际上有解决方案,该如何解决呢?


对于投票否决这个问题的人来说,“太广泛了”,为什么?我对这个问题的“范围太广”感到好奇?
user3439894 '17

这些YYYYMMDD文件夹是否全部直接位于一个主文件夹中,还是分布在更广泛的层次结构中?
nohillside

@patrix就我而言,它们都在同一目录或主文件夹中
davidjnatarajan

Answers:


8

假设所有这些YYYYMMDD文件夹都是可以运行的同一父目录的一部分

cd PARENT_DIRECTORY
for d in */; do
    [[ $d =~ [0-9]{8}/ ]] || continue
    mkdir -p -- "${d:0:4}/${d:4:2}"
    mv -- "$d" "${d:0:4}/${d:4:2}/${d:6:2}"
done
  • for d in */; do循环读取的所有目录条目,尾随/确保只有目录名实际匹配
  • [[ $d =~ [0-9]{8}/ ]] 测试当前条目是否由8位数字组成,如果不是,则继续下一个条目
  • ${d:0:4}/${d:4:2}/${d:6:2}在内部使用参数扩展bash来创建包含新路径的字符串
  • --在这两个mkdirmv防止问题的情况下,目录或文件名开头用-。这不可能在这里发生,但无论如何可能都是好的做法。

感谢@terdon和@ user3439894提供有关如何改进原始脚本的想法。


感谢您的回答,这很完美!我觉得此解决方案比@grgarside提供的解决方案更好,因为它要快得多,尤其是在处理包含数千个文本文档的庞大语料库时。
davidjnatarajan '17

8

您可以在终端中使用以下内容。cd到包含的文件夹,然后运行以下命令:

find . -type f -exec bash -c \
  'F=$(sed -E "s#^\./([0-9]{4})([0-9]{2})([0-9]{2})#\1/\2/\3#" <<< $1);\
  mkdir -p -- $(dirname "$F");\
  mv -- "$1" "$F"' - {} \;

find . -type f递归获取当前目录中的每个文件。
-exec bash -c打开一个外壳程序以运行以下命令。
F=$(…)打开一个子外壳,并在文件路径上使用sed来操纵进入文件夹的路径。
^\./([0-9]{4})([0-9]{2})([0-9]{2})是具有三个捕获组的正则表达式,如下所示: 是替换,其中每个捕获组(,等)用分隔。创建目录以将文件移入。将每个文件移到其相应的文件夹中。
\1/\2/\3\1/
mkdir -p -- $(dirname "$F")
mv -- "$1" "$F"

这将采用左侧的层次结构,并将其转换为右侧的层次结构:

├── 20170201               └── 2017
   └── abcdefghij             ├── 02
└── 20170302                      └── 01
    └── abcdefghij 2                  └── abcdefghij
                               └── 03
                                   └── 02
                                       └── abcdefghij 2

如果包含文件夹中的其他文件以日期为名称,它们将被当作文件夹移动。为防止这种情况,请将第二行替换为:

  'F=$(sed -E "s#^\./([0-9]{4})([0-9]{2})([0-9]{2})(?:/.+)#\1/\2/\3#" <<< $1);\

(?:/.+)因此该路径有一个后续的组件,确保,没有忽视其中的文件父目录的孩子任何东西。


@klanomath regex101.com
grg

@grgarside Thanx
klanomath '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.