编写创建硬链接的脚本,根据现有文件名以及是否满足某些条件对它们进行编号?

编写创建硬链接的脚本,根据现有文件名以及是否满足某些条件对它们进行编号?

首先我应该说我是一个编码菜鸟。我正在编写的剧本确实将我有限的技能推向了极限。请原谅帖子的长度。我尽量保持简短,但我认为详细程度是必要的。

我也只是对我遇到的问题给出了一个非常高层次的概述。

基本上,我需要我的脚本来创建硬链接并根据几个标准对它们进行命名/编号,但我不确定我是否以正确的方式处理事情和/或使用正确的工具。


(太多)细节。

我正在编写一个 bash 脚本,它将自动执行从 torrent 文件创建和命名硬链接的过程。我使用循环根据从 torrent 文件夹路径和 torrent 文件夹中各个文件的名称中提取的字符串来设置变量。然后,我使用变量根据某种模式(符合 Plex 的命名方案)命名硬链接。

但问题是,我需要从多个文件夹/种子创建硬链接。以下是每个 torrent(目录的 A、B 和 C)如何按照我需要的方式对文件进行编号($HardlinkDir)。

 $DirA             $DirB          $DirC                           $HardlinkDir
   │                 │              │                                  │
01.*.mp4             │              │              The Series Name - s01e01 - Episode Name.mp4
02.*.mp4             │              │              The Series Name - s01e02 - Episode Name.mp4
03.*.mp4             │              │              The Series Name - s01e03 - Episode Name.mp4
04.*.mp4             │              │              The Series Name - s01e04 - Episode Name.mp4
05.*.mp4             │              │              The Series Name - s01e05 - Episode Name.mp4
06.*.mp4             │              │              The Series Name - s01e06 - Episode Name.mp4
07.*.mp4             │              │              The Series Name - s01e07 - Episode Name.mp4
                ┌ 01.*.mkv          │              The Series Name - s01e08 - Episode Name.mkv
08.foo.mp4 ─────┼ 02.*.mkv          │              The Series Name - s01e09 - Episode Name.mkv
                └ 03.*.mkv          │              The Series Name - s01e10 - Episode Name.mkv
09.*.mp4                            │              The Series Name - s01e11 - Episode Name.mp4
                               ┌ 01.*.mkv          The Series Name - s01e12 - Episode Name.mkv
10.bar.mp4 ────────────────────┼ 02.*.mkv          The Series Name - s01e13 - Episode Name.mkv
                               └ 03.*.mkv          The Series Name - s01e14 - Episode Name.mkv
11.*.mp4                                           The Series Name - s01e15 - Episode Name.mp4

中的硬链接的名称$HardlinkDir几乎完全可以根据循环之前或循环期间定义的变量来设置。但由于“e##”数字从 e08 开始出现偏差,因此必须根据一些规则来设置数字。

每隔几周就会上传一个新版本的 TorrentA。有了它,包含字符串 , 的文件之前的文件数量foo可以变化。因此,文件名中foo出现字符串的数字也可能会有所不同。文件名中出现字符串的数字也是如此bar。有时,包含字符串foo, and的文件之间有多个文件bar......使事情变得更加复杂,有时foobar文件之间没有编号的文件。

foo带有字符串、 和, 的文件之前、之间和之后的文件数量bar可能会有所不同,文件名中的数字也可能有所不同。但琴弦foo。并且bar总是展示。

Torrents / Dirs A 和 B 总是有三个文件,而且每周它们总是编号和命名完全相同的东西。

最后一件事让事情变得有点复杂...... TorrentA (DirA) 会定期更新,因此版本 1 可能只有前四个文件。那么TorrentB可能会在TorrentA新版本发布之前上传。因此,脚本可能会尝试根据 DirA 中尚不存在的文件名派生的信息为 DirB 创建硬链接(尽管这种情况很少见)。

据我所知,我需要编写脚本来做的事情(大致按顺序)是-

  1. 将包含字符串的文件名设置foo为变量$foo...。
  2. 将包含字符串的文件名设置bar为变量...$bar

如果foobar文件不存在,则不会设置该变量。

  1. 当循环开始时,脚本需要检查正在处理的文件名 ($filename) 是否匹配$foo$bar
  2. 如果它匹配时,脚本会完全跳过该文件。
  3. 如果不匹配$fooor ,则脚本使用and/or$bar提取两位数。awksed

这应该适用于文件 01 到 07。08 将被跳过,然后 09 必须有其他参数。

  1. 如果 中的数字$filename等于 +1 中的数字$foo,但$filename不匹配,$bar则添加 +2。换句话说,如果 in 中的数字$filename是 09,则加 2 使其变为 11。

为了考虑到foobar文件之间存在多个文件的可能性,我猜测步骤 6 中设置的数字需要在循环运行时进行迭代,并且脚本还需要检查文件名中的数字是否更高比在$bar.例如....

  1. 如果 中的数字等于+1$filename中的数字,$foo $filename不匹配或者有一个比+3$bar更高的数字。$bar因此理论文件10.*.mkv将变成The Series Name - s01e11 - Episode Name.mkv.
  2. 如果$filename匹配$bar,则跳过它。
  3. (我对此有点犹豫)如果$filename(在 DirA 中记住)的数字大于$bar,那么......我不确定是什么。命名硬链接时使用的数字需要高于之前设置的数字。也许我可以使用某种计数器或将已使用的数字输出到 tmp 文件?

[注意] 至于 和 中的文件DirB,它们的编号将以类似的方式设置,但使用和文件DirC名称中的字符串(if == ; then 等等)。我还可以根据.DirADirB$filename01.*.mkv$hardlinkDir


问题。

Q1.我的脚本工作的基本工作流程大致正确吗?

Q2。我是否把事情过于复杂化了?

Q3。关于步骤 9.,是否可以在之后使用计数器来设置文件编号? $bar 值得探索吗?...我只是想不出当$foo、 之间$bar、之后的文件数量$bar可能会有所不同...或者根本不存在时如何导出数字。

答案1

基本上:您需要一个带有 N 个参数的脚本,第一个可以是生成的 HardlinkDir,然后是包含剧集名称的文件,其余的可以是 dirA、dirB、dirC 等。

对我来说,最简单的是 1) 删除 HardlinkDir 目录的内容,然后对于 dirA、dirB dirC 中按字母顺序看到的每个文件:在该文件中。标题可以来自一个单独的文件,给出您希望第 N 个文件具有的名称?

IE:

文件“series_name.txt”,您可以在其中按顺序放置所有剧集名称,每行 1 个。举个例子 :

 s01e01 - Episode Name
 s01e02 - Episode Name
 etc.

以及您为其提供参数的脚本:“HardlinkDir”“series_name.txt”“dirA”“dirB”“dirC”(...)

bash 的一个简单解决方案(调用 awk 脚本来完成繁重的工作)是:

#!/usr/bin/env bash
_usage() {
  cat <<'EOF'
   this script needs at least those arguments:
     # $1=HardLinkDir, $2=series_name.txt # containing 1 line per episode name
     # $3 to $n : the directory, in order, with the *.mp4 and *.mkv in them, in order
   it will then EMPTY the $1 directory, and re-create hard links (ln) in it.
EOF
   for msg in "$@"; do printf "Erreur: %s\n" "$msg" ; done
   exit 1
}

if [ "$#" -lt 3 ]; then
   _usage "We need at least 3 args : HardLinkDir series_name.txt dirA ... "
fi
lndir="$1" ; 
episode_list="$2" ; series_name="${2/.txt/}" ; 
[ -d "$lndir" ] || _usage "arg1 : lndir=$lndir : is not a directory"
[ -f "$episode_list" ] || _usage "arg2 : episode_list=$episode_list : is not a file"
shift 2 # we "absorbed" the first 2 args : the rest are the dirs with the movie files
arg=2
for dir in "$@"; do 
  arg=$((arg + 1))
  [ -d "$dir" ] || _usage "arg${arg}: '$dir' : is not a directory."
done  

rm "${lndir:-__must_be_nonvoid__}"/*  # delete first the files in that dir, if any

for dir in "$@"; do
  ls "${dir}"/*.???
done | awk -v series_name="${series_name}" -v lndir="${lndir}" '
 BEGIN { after_first=0 }
 (NR == FNR) { rem="we read the first file... so the episode list"
               episode[NR]=$0
 }

 ((NR != FNR) && ( after_first==0 )) { after_first=1; episode_number=0 }

 ((NR != FNR) && ( $0 ~ /..mp4|.mkv/ ) { 
   rem="NR>FNR, so we read the 2nd file, -, stdin..."
   rem="we also match .mp4 or .mkv, so we have a video file fullname as input"
   episode_number++
   fullfilename=$0; ext=fullfilename ; sub(".*[.]","",ext)
   destname = lndir "/" series_name " - " episode[episode_number] "." ext
   cmd="ln \"" fullfilename "\" \"" destname "\""
   printf("executing: %s\n",cmd)
   system(cmd); close(cmd)
 }
' "$episode_list" "-"  # first file is the episode_list file, then stdin

请注意:我只是写了这个,根本没有测试它,因为我现在无法测试它......也许将上面的“rm”和“ln”分别替换为:“echo rm”和“echo ln”,以看看会做什么...我也只使用常规的 awk 想法(因此很奇怪: ext=fullname; sub(....,ext) )

相关内容