按模式计数并移动文件

按模式计数并移动文件

我有许多 epub 文件,想将它们整理到文件夹中。我的所有文件都遵循相同的模式“作者 - 姓名(年份).epub”。我想归档的是按作者计数文件,如果书籍数量超过 2 本(例如),则将它们移动到以作者命名的文件夹中。

例如,对于以下文件:

Willis, Connie - [Oxford Time Travel #1] - Doomsday Book (1992).epub
Willis, Connie - [Oxford Time Travel #2] - To Say Nothing of the Dog (1997).epub
Willis, Connie - [Oxford Time Travel #3] - Blackout (2010).epub
Willis, Connie - [Oxford Time Travel #4] - All Clear (2010).epub
Wilson, Robert Charles - Julian Comstock - A Story of 22nd-Century America (2009).epub
Wilson, Robert Charles - [Spin Saga #1] - Spin (2005).epub

Connie Willis 的所有书籍均须移至“Willis, Connie”文件夹,因为其数量超过 2 本,而 Robert Wilson 的书籍则保持不变。

我感到非常迷茫,不知道从哪里开始。

答案1

三步解决方案。cd到文件所在的目录,然后:

  1. 这会将每个文件移动到相应的子目录:

    find . -maxdepth 1 -type f -iname "* -*.epub" \
       -exec bash -c '
           mkdir "${1%% -*}" 2>/dev/null; mv -n -- "$1" "${1%% -*}"/
       ' bash {} \;
    

    "${1%% -*}""$1"是第一个(空格+减号)的一部分-。我们有时预计子目录已经存在;mkdir然后会失败,没关系。

  2. 这将检测具有两个或更少文件的子目录并将其所有内容(返回)移动至当前工作目录:

    find . -mindepth 1 -maxdepth 1 -type d \
       -exec sh -c '
          [ $(find "$1" -maxdepth 1 -type f -printf "\n" | wc -l) -le 2 ]
       ' sh {} \; \
       -exec sh -c '
          find "$1" -mindepth 1 -maxdepth 1 -exec mv -n -t ./ -- \{\} +
       ' sh {} \;
    

    更改-le 2片段以调整数字。您可能想知道为什么我告诉find打印换行符而不是文件名(默认行为)。这是因为这wc是一个文本工具,文件名中可能出现的换行符会破坏我的逻辑。明确地为每个文件打印一个换行符可以解决这个问题。

  3. 这将删除空目录:

    find . -maxdepth 1 -type d -empty -delete
    

    即使没有它,它也应该可以工作,-empty因为-delete(像rmdir)只会在目录为空时删除目录。但是在这种情况下,我想隐藏预期的错误消息,告诉我给定的目录不为空。2>/dev/null但是,使用 执行此操作也会阻止我看到意外的错误消息。因此无论如何-empty

逐步运行这些或构建脚本。建议事先备份您的目录结构(例如cp -lr my_directory my_directory_backup)以防万一。我使用的某些选项是非 POSIX 的,这些选项可能不适合您。此外,如果您已经有任何子目录,我的解决方案可能会破坏它们;然后根据您的需要进行调整。

相关内容