【问题标题】:Make directory based on filenames before fourth underscore根据第四个下划线之前的文件名创建目录
【发布时间】:2022-01-23 09:48:12
【问题描述】:

我有这些测试文件:

ABCD1234__12_Ab2_Hh_3P.mp4
ABCD1234__12_Ab2_Lw_3P.wmv
ABCD1234__12_Ab2_SSV.mov
EFGH56789__13_Mn1_SSV.avi
EFGH56789__13_Mn1_Ve1_3P.mp4
EFGH56789__13_Mn1_Ve2_3P.webm

我想在 Automator 中创建一个上下文服务,它根据上面的文件名前缀创建目录,如下所示:

ABCD1234__12_Ab2
EFGH56789__13_Mn1

...并相应地将文件移动到这两个中。名称中唯一一致的变量是下划线,所以我想我可以用这些来描述,最好在第四个之前捕获名称。

我最初是从这个非常简单的脚本开始的:

for file in "$@"
do
mkdir "${file%.*}" && mv "$file" "${file%.*}"
done

它为每个文件创建一个文件夹并将每个文件移动到自己的文件夹中。

我尝试添加变量、各种 if/then 等,但无济于事(不是职业程序员)。

我还编写了另一个脚本以稍微不同的方式执行此操作,但结果相同:

for folder in "$@"
do
cd "$1"
find . -type f -maxdepth 1 -exec bash -c 'mkdir -p "${0%.*}"' {} \; \
-exec bash -c 'mv "$0" "${0%.*}"' {} \;
done

我觉得我缺少一些明显的东西。

【问题讨论】:

  • 为什么你的循环不使用$folder
  • 我认为没有一种简单的方法可以使用 bash 参数扩展运算符来做你想做的事情。你可以用sed来做。
  • 您能否更具体地说明从文件名派生目录名时要遵循的规则? IE。模式是否总是{ALPHA_NUMERIC_CHARACTERS}__{TWO_DIGITS}_{MORE_ALPHA_NUMERIC_CHARACTER}_{IGNORED_CHARACTERS}?或者模式会是别的什么?

标签: bash automator


【解决方案1】:

您的脚本按点分割,但您说要按下划线分割。如果您要拆分的那个是最后一个,则修复很简单:

for file in "$@"
do
    mkdir -p "${file%_*}" && mv "$file" "${file%_*}"
done

要准确获得第四个,请尝试

for file in "$@"
do
    tail=${file#*_*_*_*_}
    dir=${file%_"$tail"}
    mkdir -p "$dir" && mv "$file" "$dir"
done

如果您想在此处使用&&,则添加-p 选项是必要的错误修复;如果目录已经存在,mkdir 没有这个选项将会失败。

也许另请参阅 the section about parameter expansions in the Bash Reference Manual,它解释了这种语法及其变体。

【讨论】:

  • $tail 可能值得引用。
  • @konsolebox 很好,谢谢
  • 第二个选项效果很好。我之前通过一些试验和错误自己做了类似的事情,并且正在阅读关于需要“-p”但你的优雅和简单!
【解决方案2】:

你可以这样做:

#!/bin/bash
shopt -s extglob

for file
do
    if [[ $file =~ ^(([^_]*_){3}[^_]*) ]]
    then
        echo "${BASH_REMATCH[0]}"
    else
        echo "${file%.*}"
    fi
done

【讨论】:

  • 我无法让这个工作(很可能是我的错),但 Tripleee 成功了!