AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1530025
Accepted
user6790086
user6790086
Asked: 2024-10-15 12:40:01 +0800 CST2024-10-15 12:40:01 +0800 CST 2024-10-15 12:40:01 +0800 CST

递归地将字幕文件移动到子目录中

  • 772

我目前在运行 ubuntu 的 Beelink 上运行 plex,到目前为止,与每部电影相关的所有文件(电影文件、相关图像和字幕)都在同一个父目录中。大多数情况下这没问题,但对于有多个字幕的电影,可能会变得混乱。例如

    /Movies
       /Avatar (2009)
          Avatar (2009).mkv
          Avatar (2009).eng.srt
          Avatar (2009).en.forced.ass
          Avatar (2009).en.sdh.srt
          Avatar (2009).de.srt
          Avatar (2009).de.sdh.forced.srt

现在看来 plex 会在“subs”或“subtitles”文件夹中找到字幕位置。那么为了整理一下,我该如何递归遍历父电影目录,并针对每个单独的电影文件夹,将所有字幕文件移动到“subtitles”文件夹中,就像这样?

/Movies
   /Avatar (2009)
      Avatar (2009).mkv
      /Subtitles
         Avatar (2009).eng.srt
         Avatar (2009).en.sdh.srt
         Avatar (2009).de.srt
         Avatar (2009).de.sdh.forced.srt

对于电视节目,父文件夹下可能有多个级别,例如

**Old:**


/TV Shows
   /Game Of Thrones
      /Season 02
         Game Of Thrones - s02e03.mp4
         Game Of Thrones - s02e03.eng.srt
         Game Of Thrones - s02e03.en.forced.srt


**New:**
         
TV Shows
   /Game Of Thrones
      /Season 01
         Game Of Thrones - s01e03.mp4
         Game Of Thrones - s01e04.mp4
         /Subtitles
           Game Of Thrones - s01e03.eng.srt
           Game Of Thrones - s01e04.eng.srt
      /Season 02
         Game Of Thrones - s02e03.mp4
         /Subs
           Game Of Thrones - s02e03.eng.srt
           Game Of Thrones - s02e03.en.forced.srt

更好的选择是仅当尚未在字幕文件夹中时才移动......

command-line
  • 2 2 个回答
  • 367 Views

2 个回答

  • Voted
  1. Best Answer
    kos
    2024-10-15T14:11:48+08:002024-10-15T14:11:48+08:00
    find . -name 'Subtitles' -prune -o -type f -name '*.srt' -printf '%h\0' | sort -zu | while IFS= read -d '' -r d; do
        printf "Creating '%s'...\n" "${d}/Subtitles"
        printf "Moving '%s' to '%s'...\n" "${d}/*.srt" "${d}/Subtitles"
    done
    

    .srt将以递归方式查找当前工作目录中每个文件的路径,排除名为“Subtitles”的目录中包含的文件,仅打印其基本名称并过滤掉重复项,在每个结果路径内创建一个“Subtitles”目录(如果不存在)并移动.srt其中每个文件。

    它将处理.srt位于当前工作目录任何深度的文件,以及“电视节目”目录。

    该命令将执行试运行;如果输出看起来不错,则运行实际命令:

    find . -name 'Subtitles' -prune -o -type f -name '*.srt' -printf '%h\0' | sort -zu | while IFS= read -d '' -r d; do
        mkdir -p "${d}/Subtitles"
        mv "${d}"/*.srt "${d}/Subtitles"
    done
    

    % tree -a
    .
    ├── foo
    │   └── bar
    │       ├── baz
    │       │   └── Subtitles
    │       │       └── sub_baz.srt
    │       └── sub_bar.srt
    └── sub.srt
    
    5 directories, 3 files
    % find . -name 'Subtitles' -prune -o -type f -name '*.srt' -printf '%h\0' | sort -zu | while IFS= read -d '' -r d; do
        mkdir -p "${d}/Subtitles"
        mv "${d}"/*.srt "${d}/Subtitles"
    done
    % tree -a
    .
    ├── foo
    │   └── bar
    │       ├── baz
    │       │   └── Subtitles
    │       │       └── sub_baz.srt
    │       └── Subtitles
    │           └── sub_bar.srt
    └── Subtitles
        └── sub.srt
    
    7 directories, 3 files
    
    • 5
  2. terdon
    2024-10-15T23:37:59+08:002024-10-15T23:37:59+08:00

    这是另一种方法。使用 bash 的globstar选项允许递归到子目录中。来自man bash:

    全球星

    如果设置,路径名扩展上下文中使用的模式**将匹配所有文件和零个或多个目录和子目录。如果模式后跟/,则仅匹配目录和子目录。

    因此**/只会匹配目录,但会包含子目录。考虑到这一点,你可以这样做:

    shopt -s globstar
    for d in **/; do mkdir -p "$d/Subtitles" && mv "$d/"*.srt "$d"/Subtitles ; done
    rmdir **/Subtitles/
    

    我使用以下一组文件和目录对其进行了测试:

    $ tree
    .
    ├── a
    ├── b
    ├── Movies
    │   └── Avatar
    │       ├── Avatar (2009).de.sdh.forced.srt
    │       ├── Avatar (2009).de.srt
    │       ├── Avatar (2009).en.forced.ass
    │       ├── Avatar (2009).eng.srt
    │       ├── Avatar (2009).en.sdh.srt
    │       └── Avatar (2009).mkv
    └── TV Shows
        └── Game Of Thrones
            └── Season 02
                ├── Game Of Thrones - s02e03.emg.srt
                ├── Game Of Thrones - s02e03.en.forced.srt
                └── Game Of Thrones - s02e03.mp4
    
    6 directories, 11 files
    

    运行上述命令后,我得到以下结果:

    $ tree
    .
    ├── a
    ├── b
    ├── Movies
    │   └── Avatar
    │       ├── Avatar (2009).en.forced.ass
    │       ├── Avatar (2009).mkv
    │       └── Subtitles
    │           ├── Avatar (2009).de.sdh.forced.srt
    │           ├── Avatar (2009).de.srt
    │           ├── Avatar (2009).eng.srt
    │           └── Avatar (2009).en.sdh.srt
    └── TV Shows
        └── Game Of Thrones
            └── Season 02
                ├── Game Of Thrones - s02e03.mp4
                └── Subtitles
                    ├── Game Of Thrones - s02e03.emg.srt
                    └── Game Of Thrones - s02e03.en.forced.srt
    
    8 directories, 11 files
    

    请注意,如果目录中没有 srt 文件,它会抛出一些警告,因为它会尝试运行,mv directory_name/*srt directory_name/Subtitles但由于*.srtglob 不匹配任何内容,它会返回自身(除非您nullglob激活了该选项),并且由于没有文件名称为*srt,它会失败。这也是我必须添加rmdir **/Subtitles删除空Subtitles目录的原因。您可以安全地添加2> /dev/null到命令末尾mv以隐藏这些警告。

    或者,您可以做一些稍微复杂一点的事情,并且只创建目录并在您知道有*.srt文件时尝试复制:

    shopt -s globstar
    shopt -s nullglob
    for d in **/; do 
      subs=( "$d"/*.srt ) 
      [[ ${#subs[@]} -gt 0 ]] && 
        mkdir -p "$d"/Subtitles && 
          mv "$d"/*srt "$d"/Subtitles
    done
    

    这样一次传递就能得到所需的输出。为了避免移动已经在Subtitles目录中的文件,请使用extglobbash 选项,该选项允许您构建更复杂的 glob,并查找名称不是 的任何目录Subtitles:

    shopt -s globstar nullglob extglob
    for d in **/!(Subtitles)/; do 
      subs=( "$d"/*.srt ) 
      [[ ${#subs[@]} -gt 0 ]] && 
        mkdir -p "$d"/Subtitles && 
          mv "$d"/*srt "$d"/Subtitles
    done
    
    • 4

相关问题

  • 如何从命令行仅安装安全更新?关于如何管理更新的一些提示

  • 如何从命令行刻录双层 dvd iso

  • 如何从命令行判断机器是否需要重新启动?

  • 文件权限如何工作?文件权限用户和组

  • 如何在 Vim 中启用全彩支持?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve