通过匹配 bash 脚本中的正则表达式模式在不同条件下重命名多个文件夹?

问题描述 投票:0回答:1

举个例子,假设我有一个包含这些文件夹的文件夹:

Universal 2023 02 15 Some Name
Universal 2023 02 15 Some Name and Words After
Sony Some Name 2023 02 15
Sony Some Name 2023 02 15 and Words After

Desired output

Some Name - 2023 02 15 - Universal
Some Name - 2023 02 15 - And Words After - Universal
Some Name - 2023 02 15 - Sony
Some Name - 2023 02 15 - and Words After – Sony

我为每个名称结构写了一个命令。

1。 « Universal 2023 02 15 Some Name » 将更名为: « 一些名字 - 2023 02 15 - 通用 » 使用此命令:

rename -v 's/([\s\S]+)\s((\d{4})\s(\d{2})\s(\d{2}))\s(([\s\S]+)\s([\s\S]+))/$6 - $2 - $1/g' *

« Universal 2023 02 15 Some Name and Words After » 将更名为: « 一些名字 - 2023 02 15 - 之后的话 - 通用 » 使用此命令:

rename -v 's/([\s\S]+)\s((\d{4})\s(\d{2})(\s)(\d{2}))\s((\w+)\s(\w+))\s([\s\S]+)/$7 - $2 - $10 - $1/g' *

« Sony Some Name 2023 02 15 » 将更名为: « 一些名字 - 2023 02 15 - 索尼 » 使用此命令:

rename -v 's/([\s\S]+)\s((\w+)\s(\w+))\s((\d{4})\s(\d{2})\s(\d{2}))/$2 - $5 - $1/g' *
  1. 最后, « Sony Some Name 2023 02 15 and Words After » 将更名为: « 一些名字 - 2023 02 15 - 和之后的词 - 索尼 » 使用此命令:
rename -v 's/([\s\S]+)\s((\d{4})\s(\d{2})\s(\d{2}))\s(([\w]+)\s([\w]+))\s([\s\S]+)/$6 - $2 - $9 - $1/g' *

当我想重命名这些文件夹时,我必须将它们归类到单独的文件夹中并运行相应的命令,然后在完成后将它们全部放回同一个文件夹中。它很烦人。所以我想在 bash 中编写一个脚本,以避免将它们单独归档并使所有内容都从主文件夹开始。在 VS 代码中,除了重命名命令外,一切似乎都很好。 这条线是橙色的......意味着缺少一些东西但我不知道它是什么:

's/([\s\S]+)\s((\d{4})\s(\d{2})\s(\d{2}))\s(([\w]+)\s([\w]+))\s([\s\S]+)/$6 - $2 - $9 - $1/g'

查看此链接以查看 VS 代码颜色的 scipt: https://i.stack.imgur.com/tosSv.png

我的剧本:

for i in $*/; do
        # for Universal 2023 02 15 Some Name
        if [[ "$i" =~ ([\s\S]+)\s((\d{4})\s(\d{2})\s(\d{2}))\s(([\s\S]+)\s([\s\S]+)) ]];
                then
                        rename -v 's/([\s\S]+)\s((\d{4})\s(\d{2})\s(\d{2}))\s(([\s\S]+)\s([\s\S]+))/$6 - $2 - $1/g' *
        
        # for Universal 2023 02 15 Some Name and Words After
        elif [[ "$i" =~ ([\s\S]+)\s((\d{4})\s(\d{2})(\s)(\d{2}))\s((\w+)\s(\w+))\s([\s\S]+) * ]];
                then
                        rename -v 's/([\s\S]+)\s((\d{4})\s(\d{2})(\s)(\d{2}))\s((\w+)\s(\w+))\s([\s\S]+)/$7 - $2 - $10 - $1/g' *

        # for Sony Some Name 2023 02 15
        elif [[ "$i" =~ ([\s\S]+)\s((\w+)\s(\w+))\s((\d{4})\s(\d{2})\s(\d{2})) ]];
                then
                        rename -v 's/([\s\S]+)\s((\w+)\s(\w+))\s((\d{4})\s(\d{2})\s(\d{2}))/$2 - $5 - $1/g' *
        
        # for Sony Some Name 2023 02 15 and Words After
        else [[ "$i" =~ ([\s\S]+)\s((\w+)\s(\w+))\s((\d{4})\s(\d{2})\s(\d{2})) ]];
                then
                        rename -v 's/([\s\S]+)\s((\d{4})\s(\d{2})\s(\d{2}))\s(([\w]+)\s([\w]+))\s([\s\S]+)/$6 - $2 - $9 - $1/g' *
        
        fi

done

the script in color for VS code. My commands are all orange...

任何人都可以帮助我!!!!!!!!! 非常感谢! 马丁

regex bash pattern-matching batch-rename
1个回答
0
投票

试试这个 Shellcheck-干净的代码:

#! /bin/bash -p

sep_rx='[[:space:]]+'
part_rx='[^[:space:]]+'
company_rx=$part_rx
name_rx="${part_rx}${sep_rx}${part_rx}"
date_rx="[[:digit:]]{4}${sep_rx}[[:digit:]]{2}${sep_rx}[[:digit:]]{2}"
after_rx="${part_rx}(${sep_rx}${part_rx})*"

cdn_rx="^($company_rx)$sep_rx($date_rx)$sep_rx($name_rx)\$"
cdna_rx="^($company_rx)$sep_rx($date_rx)$sep_rx($name_rx)$sep_rx($after_rx)\$"
cnd_rx="^($company_rx)$sep_rx($name_rx)$sep_rx($date_rx)\$"
cnda_rx="^($company_rx)$sep_rx($name_rx)$sep_rx($date_rx)$sep_rx($after_rx)\$"

for d in */; do
    dir=${d%/}
    if [[ $dir =~ $cdn_rx ]]; then
        company=${BASH_REMATCH[1]}
        date=${BASH_REMATCH[2]}
        name=${BASH_REMATCH[3]}
        newdir="$name - $date - $company"
    elif [[ $dir =~ $cdna_rx ]]; then
        company=${BASH_REMATCH[1]}
        date=${BASH_REMATCH[2]}
        name=${BASH_REMATCH[3]}
        words_after=${BASH_REMATCH[4]}
        newdir="$name - $date - $words_after - $company"
    elif [[ $dir =~ $cnd_rx ]]; then
        company=${BASH_REMATCH[1]}
        name=${BASH_REMATCH[2]}
        date=${BASH_REMATCH[3]}
        newdir="$name - $date - $company"
    elif [[ $dir =~ $cnda_rx ]]; then
        company=${BASH_REMATCH[1]}
        name=${BASH_REMATCH[2]}
        date=${BASH_REMATCH[3]}
        words_after=${BASH_REMATCH[4]}
        newdir="$name - $date - $words_after - $company"
    else
        printf 'ERROR: Failed to match: %s\n' "$dir" >&2
        exit 1
    fi
    mv -v -- "$dir" "$newdir"
done
© www.soinside.com 2019 - 2024. All rights reserved.