ハードリンクを作成し、既存のファイル名と特定の条件を満たすかどうかに応じて番号を付けるスクリプトを作成しますか?

ハードリンクを作成し、既存のファイル名と特定の条件を満たすかどうかに応じて番号を付けるスクリプトを作成しますか?

私はコーディング愚かな奴だと言って始める必要があります。私が書いている台本は私の限られた能力を限界まで押し付けることです。投稿が長くなった点ご了承ください。簡単に説明しようとしましたが、詳細なレベルが必要だと思います。

私はまた、私が経験している問題について非常に高いレベルの概要を提供しています。

基本的に、ハードリンクを作成し、いくつかの基準に基づいて名前/番号を指定するには、スクリプトが必要ですが、正しい方法で作業しているのか、および/または正しいツールを使用しているのかわかりません。


(多すぎる)詳細。

私は急流ファイルからハードリンクを作成し、名前を付けるプロセスを自動化するbashスクリプトを書いています。私はTorrentフォルダパスから抽出した文字列とTorrentフォルダ内の個々のファイルの名前に基づいて変数を設定するためにループを使用します。次に、変数を使用してパターンに従ってハードリンクの名前を指定します(Plexの命名スキームに従って)。

しかし、問題は、複数のフォルダ/急流からハードリンクを作成する必要があることです。各トレント(ディレクトリ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、文字列を含むファイルの間に複数のファイルがあり、作業をbarより複雑にするために、ファイル間に番号が付けられたファイルがないことがありますfoobar

foo文字列、および、前、間、および後のファイル数は、barファイル名の数と同じように異なる場合があります。しかし、文字列はfoo。そしてbarいつも展示する。

Torrents / Dirs AとBには常に3つのファイルがあり、毎週ファイル番号と名前は常にまったく同じです。

状況を少し複雑にする最後のこと... TorrentA(DirA)は定期的に更新されるため、バージョン1には最初の4つのファイルしかありません。これにより、TorrentBはTorrentAの新しいバージョンがリリースされる前にアップロードできます。したがって、これらのケースはまれですが、スクリプトはDirAにまだ存在しないファイル名から派生した情報に基づいてDirBへのハードリンクを生成しようとする可能性があります。

私が知っている限り、実行するスクリプトを作成するために必要な作業(おおよその順序で)は次のとおりです。

  1. 文字列を含むファイル名をfoo変数に設定します$foo
  2. 文字列を含むファイル名をbar変数に設定します。$bar

fooまたは、ファイルが存在しない場合、bar変数は設定されません。

  1. ループが開始されると、スクリプトは処理中のファイル名($ filename)が一致することを確認する必要があります$foo$bar
  2. その場合する一致すると、スクリプトはファイルを完全にスキップします。
  3. orが一致しない場合、$fooスクリプトはand / orを使用して$bar2桁の数字を抽出します。awksed

これはファイル01から07まで機能します。 08はスキップし、09には異なるパラメータが必要です。

  1. 数字が$filename+1の数字と同じです$fooが、$filename一致しない場合は$bar+2が追加されます。つまり、in の数字が$filename09 なら 2 を加えて 11 になります。

fooその間に複数のファイルがある可能性を説明するために、ループが実行されてbarいる間に手順6で設定された数字を繰り返す必要があります。スクリプトにはファイル名の数字があります$bar。たとえば.... ..

  1. の数字が$filename+1の数字と等しい場合、$fooしかし、 $filename一致しないか、$bar+3より高い数値を持ちます。$barしたがって、理論文書10.*.mkvThe 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番目のファイルに割り当てたい名前が与えられた場合、タイトルは別のファイルから出ることができますか?

つまり:

すべてのエピソード名を1行に1つずつ順番に入力できる「series_name.txt」ファイル。たとえば、

 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))。

関連情報