使用正则表达式在 Mac OS 终端中重命名文件或从 Windows 脚本进行翻译

使用正则表达式在 Mac OS 终端中重命名文件或从 Windows 脚本进行翻译

我需要有关 macOS 的 shell 脚本的帮助,以使用特定模式重命名文件。该脚本只能处理一个文件,而不是多个。

以下是三个例子:

A。公开演讲_ (189) 与神同行带来现在和永远的祝福 — Chris Ruscher 10_28_2023.mp3

会成为

189 - 与神同行带来现在和永远的祝福 - Chris Ruscher - 2023-10-28-0900.mp3

b.公开演讲_ (55) 你怎样才能在神面前有好名声? — 格雷戈里·杜洪 11_4_2023.mp3

会成为

055 怎样才能在神面前有好名声? - 格雷戈里·杜洪 - 2023-11-04-0900.mp3

C。公开演讲_ (9) 与神同行带来祝福,从现在到永远 — Chris Ruscher 10_28_2023.mp3

会成为

009 - 与神同行带来祝福现在和永远 - 克里斯·鲁舍尔 - 2023-10-28-0900.mp3

所以本质上,最终的格式和顺序应该是:track number, title, speaker name, 和timestamp

  1. 删除前缀“Public Talks_”
  2. 根据需要将曲目编号隔离为带有前导零的 3 位数字
  3. 所有 4 个元素之间的破折号
  4. 将日期重新格式化为时间戳,如 yyyy-mm-dd-0900

然后,我将获取 shell 脚本并在此对话框中的每个文件中使用它(无需迭代):

请注意,传递给 shell 脚本的文件变量需要写为“$1”,如下面的对话框所示。

插入 shell 脚本窗口

有人帮助我创建了一个,但它仅适用于 Windows,并且不考虑“$1”作为文件,并且设置为处理多个文件。我需要它在 macOS 上一次处理一个文件。

#!/bin/bash
for file in *.mp3; do
    # Remove "Public Talks_"
    newname=${file#"Public Talks_ "}
    # Extract the track number and pad with leading zeros
    track=$(echo $newname | grep -o -E '\([0-9]+\)' | tr -d '()' | awk '{printf "%03d\n", $0}')
    # Remove track number and trailing spaces
    newname=$(echo $newname | sed -E 's/\([0-9]+\)//' | sed 's/^ *//')
    # Extract the title and speaker
    title=$(echo $newname | awk -F '—' '{print $1}' | sed 's/ *$//')
    speaker=$(echo $newname | awk -F '—' '{print $2}' | awk '{print $1, $2}')
    # Extract the date and reformat
    date=$(echo $newname | grep -o -E '[0-9]+_[0-9]+_[0-9]+' | tr '_' '-' | awk -F- '{print $3"-"$1"-"$2"-0900"}')
    # Concatenate all elements with dashes
    newname="$track - $title - $speaker - $date.mp3"
    # Rename the file
    mv "$file" "$newname"
done

任何人都可以将其翻译成正确的 macOS 语法或编写更简洁的 shell 脚本吗?

答案1

在 zsh 中,从包含这些文件的目录中运行:

autoload -Uz zmv
zmv -n '*_ \((<0-999>)\)(* )—( * )(<1-12>)_(<1-31>)_(<1900-2100>)(.mp3)' \
       '${(l[3][0])1} -$2-$3- $6-${(l[2][0])5}-${(l[2][0])4}-0900$7'

例子:

$ autoload -Uz zmv
$ zmv -n '*_ \((<0-999>)\)(* )—( * )(<1-12>)_(<1-31>)_(<1900-2100>)(.mp3)' \
         '${(l[3][0])1} -$2-$3- $6-${(l[2][0])5}-${(l[2][0])4}-0900$7'
mv -- 'Public Talks_ (189) Walking With God Brings Blessings Now and Forever — Chris Ruscher 10_28_2023.mp3' '189 - Walking With God Brings Blessings Now and Forever - Chris Ruscher - 2023-28-10-0900.mp3'
mv -- 'Public Talks_ (55) How Can You Make a Good Name With God? — Gregory Duhon 11_4_2023.mp3' '055 - How Can You Make a Good Name With God? - Gregory Duhon - 2023-4-11-0900.mp3'
mv -- 'Public Talks_ (9) Walking With God Brings Blessings Now and Forever — Chris Ruscher 10_28_2023.mp3' '009 - Walking With God Brings Blessings Now and Forever - Chris Ruscher - 2023-28-10-0900.mp3'

如果满意,请删除-n(试运行)。

如果那必须是一个以文件名作为参数的 shell 脚本:

#! /bin/zsh -
set -o extendedglob
pattern='(#b)*_ \((<0-999>)\)(* )—( * )(<1-12>)_(<1-31>)_(<1900-2100>)(.mp3)'
ret=0
for file {
  if [[ $file = $~pattern ]] {
    argv=( "$match[@]" )
    mv -i -- $file "${(l[3][0])1} -$2-$3- $6-${(l[2][0])5}-${(l[2][0])4}-0900$7" || ret=$?
  } else {
    print -ru2 "Skipping $file which doesn't match the pattern"
  }
}
exit $ret

但您会缺少 的额外保障措施zmv

请注意,我们循环遍历脚本的所有参数,而不是仅处理第一个 ( $1)。

相关内容