나는 코딩 멍청한 놈이라고 말하면서 시작해야합니다. 제가 쓰고 있는 대본은 제 제한된 능력을 한계까지 밀어붙이는 것입니다. 포스팅이 길어진 점 양해 부탁드립니다. 간략하게 설명하려고 노력했지만 세부적인 수준이 필요하다고 생각합니다.
나는 또한 내가 겪고 있는 문제에 대해 매우 높은 수준의 개요를 제공하고 있습니다.
기본적으로 하드 링크를 만들고 몇 가지 기준에 따라 이름/번호를 지정하려면 스크립트가 필요하지만 올바른 방법으로 작업을 진행하고 있는지 및/또는 올바른 도구를 사용하고 있는지 잘 모르겠습니다.
(너무 많음) 세부정보.
저는 토렌트 파일에서 하드 링크를 생성하고 이름을 지정하는 프로세스를 자동화하는 bash 스크립트를 작성 중입니다. 저는 토렌트 폴더 경로에서 추출한 문자열과 토렌트 폴더에 있는 개별 파일의 이름을 기반으로 변수를 설정하기 위해 루프를 사용합니다. 그런 다음 변수를 사용하여 패턴에 따라 하드 링크의 이름을 지정합니다(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
... 일을 더 복잡하게 만들기 위해 때로는 파일 사이에 번호가 매겨진 파일이 없는 경우도 있습니다 foo
.bar
foo
문자열 , 및 , 앞, 사이, 뒤의 파일 수는 bar
파일 이름의 숫자와 마찬가지로 다를 수 있습니다. 하지만 문자열은 foo
. 그리고 bar
는언제나전시하다.
Torrents/Dirs A와 B에는 항상 세 개의 파일이 있으며, 매주 파일 번호와 이름은 항상 정확히 동일합니다.
상황을 조금 복잡하게 만드는 마지막 사항... TorrentA(DirA)는 정기적으로 업데이트되므로 버전 1에는 처음 4개의 파일만 있을 수 있습니다. 그러면 TorrentB는 TorrentA의 새 버전이 출시되기 전에 업로드할 수 있습니다. 따라서 이러한 경우는 드물지만 스크립트는 DirA에 아직 존재하지 않는 파일 이름에서 파생된 정보를 기반으로 DirB에 대한 하드 링크를 생성하려고 시도할 수 있습니다.
내가 알 수 있는 한, 수행할 스크립트를 작성하는 데 필요한 작업(대략 순서대로)은 다음과 같습니다.
- 문자열이 포함된 파일 이름을
foo
변수로 설정합니다$foo
.... - 문자열이 포함된 파일 이름을
bar
변수로 설정합니다...$bar
foo
또는 파일이 없으면 bar
변수가 설정되지 않습니다.
- 루프가 시작되면 스크립트는 처리 중인 파일 이름($filename)이 일치하는지 확인해야 합니다
$foo
.$bar
- 그 경우하다일치하면 스크립트는 파일을 완전히 건너뜁니다.
- or가 일치하지 않으면
$foo
스크립트는 and/or를 사용하여$bar
두 자리 숫자를 추출합니다.awk
sed
이는 파일 01부터 07까지 작동합니다. 08은 건너뛰고 09에는 다른 매개변수가 있어야 합니다.
- 숫자가
$filename
+1의 숫자와 동일$foo
하지만$filename
일치하지 않으면$bar
+2가 추가됩니다. 즉, in 의 숫자가$filename
09라면 2를 더해 11이 됩니다.
foo
그 사이 에 여러 파일이 있을 가능성을 설명하기 위해 bar
루프가 실행되는 동안 6단계에서 설정된 숫자를 반복해야 하며 스크립트는 파일 이름의 숫자가 $bar
. 예를 들어.... ..
- 의 숫자가
$filename
+1의 숫자와 같을 경우,$foo
하지만$filename
일치하지 않거나$bar
+3보다 높은 숫자를 갖습니다.$bar
따라서 이론 문서10.*.mkv
는The Series Name - s01e11 - Episode Name.mkv
. $filename
일치 하는 경우$bar
건너뜁니다.- (이건 좀 의구심이 듭니다.)
$filename
숫자(DirA에 기억된)가 다음보다 큰 경우$bar
... 무엇인지 잘 모르겠습니다. 하드링크의 이름을 지정할 때 사용되는 번호는 이전에 설정한 번호보다 높아야 합니다. 어쩌면 일종의 카운터를 사용하거나 사용된 숫자를 tmp 파일로 출력할 수 있을까요?
[참고] 및 에 있는 파일의 경우 DirB
해당 번호는 유사한 방식으로 설정되지만 DirC
및 파일 이름에 있는 문자열을 사용합니다(if == ; then 등). 나는 아직도 그것에 의지할 수 있다.DirA
DirB
$filename
01.*.mkv
$hardlinkDir
질문.
Q1. 내 스크립트 작업의 기본 워크플로가 대략적으로 정확합니까?
Q2. 내가 일을 너무 복잡하게 만들고 있는 걸까?
Q3. 9단계와 관련하여 나중에 카운터를 사용하여 파일 번호를 설정할 수 있습니까? $bar
탐험해 볼 가치가 있나요?$foo
... 파일 수가 , 사이 $bar
, 이후 ... 또는 전혀 존재하지 않을 때 $bar
파일 수가 다를 수 있는 경우 숫자를 내보내는 방법을 알 수 없습니다 .
답변1
기본적으로 N 매개변수가 있는 스크립트가 필요합니다. 첫 번째 매개변수는 생성된 HardlinkDir일 수 있고, 그 다음에는 에피소드 이름이 포함된 파일이고, 나머지는 dirA, dirB, dirC 등이 될 수 있습니다.
나에게 가장 쉬운 방법은 1) HardlinkDir 디렉터리의 내용을 삭제한 다음 dirA, dirB 및 dirC에 있는 모든 파일을 알파벳 순서로 해당 파일에서 삭제하는 것입니다. N번째 파일에 지정하려는 이름이 주어지면 제목은 별도의 파일에서 나올 수 있습니까?
즉:
모든 에피소드 이름을 한 줄에 하나씩 순서대로 입력할 수 있는 "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) ).