How about sharing our format expressions?

All about user-defined episode / movie / file name format expressions
AbedlaPaille
Posts: 107
Joined: 12 Apr 2020, 04:02

Re: How about sharing our format expressions?

Post by AbedlaPaille »

Abed Movies

Code: Select all

E:/{fn =~ /3D/ ? 'Films 3D' : 'Films'}/{norm = {it.upperInitial().replaceTrailingBrackets().replaceAll(/[`´‘’ʻ""“”]/, "'").replaceAll(/[:|]/, " - ").replaceAll(/[?]/, "!").replaceAll(/[*\s]+/, " ").replaceAll(/\b[IiVvXx]+\b/, { it.upper() }).replaceAll(/\b[0-9](?i:th|nd|rd)\b/, { it.lower() })}; {info.OriginalLanguage != /en/ ? norm(n) : norm(primaryTitle)}}{info.OriginalName != n && ! (info.OriginalLanguage ==~ /(en|fr)/) ? ' ('+norm(primaryTitle)+')' :""}{fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':""} ({y}){' ['+vf.match(/720[pP]|1080[pP]/)+']'}{video.CodecID =~ /hev1|hevc|HEVC/ ? ' [HEVC]' : ''}/{info.OriginalLanguage != /en/ ? norm(n) : norm(primaryTitle)}{info.OriginalName != n && ! (info.OriginalLanguage ==~ /(en|fr)/) ? ' ('+norm(primaryTitle)+')' :""}{fn.contains('3D') || fn.contains('3-D') ? ' '+'3D':""} ({y}){' [' + fn.matchAll(/UNCENSORED|UNRATED|REMASTERED|EXTENDED|UNCUT|DIRECTOR\'?S[ ._-]CUT|THEATRICAL[ ._-]CUT|ULTIMATE[ ._-]CUT|FINAL[ ._-]CUT|SPECIAL[ ._-]EDITION/)*.upper().sort().join(' ').replaceAll(/[.]/, " ") + ']'}{' ['+vs.match(/BluRay/)+']'}{' ['+vf.match(/720[pP]|1080[pP]/)+']'}{video.CodecID =~ /hev1|hevc|HEVC/ ? ' [HEVC]' : ''}{if (bitdepth == 10) ' [10bit]'}{if (af == (/6ch/)) ' [5.1]'}{" CD$pi"}{'.'+lang}{if (dc > 1) " ($di)"}
  • All movies are in preferred language French except English ones -> English
  • Adds original title if it's neither an english nor french movie
  • Retains quality if 720p/1080p / Retains source if BluRay / Retains bitdepth if 10bit / Retains codec if HEVC / Retains af if 6ch (prints 5.1)
  • Deals with multiple subtitles in same language by adding (1), (2), (3)
  • Retains movie tags like remastered, extended, 3D
  • Special folder for 3D movies
  • Invalid characters replacement
Examples
E:/Films/E.T. The Extra-Terrestrial (1982) [1080p]/E.T. The Extra-Terrestrial (1982) [BluRay] [1080p] [5.1]
E:/Films/Entre Les Murs (2008)/Entre Les Murs (2008)
E:/Films/Four Weddings And A Funeral (1994) [1080p] [HEVC]/Four Weddings And A Funeral (1994) [REMASTERED] [BluRay] [1080p] [HEVC] [10bit] [5.1]
E:/Films/Four Weddings And A Funeral (1994) [1080p] [HEVC]/Four Weddings And A Funeral (1994) [REMASTERED] [BluRay] [1080p] [HEVC] [10bit] [5.1].eng (1)
E:/Films/Four Weddings And A Funeral (1994) [1080p] [HEVC]/Four Weddings And A Funeral (1994) [REMASTERED] [BluRay] [1080p] [HEVC] [10bit] [5.1].eng (2)
E:/Films 3D/How To Train Your Dragon 3D (2010) [1080p]/How To Train Your Dragon 3D (2010) [BluRay] [1080p] [5.1]
Still trying to figure out having collections and movies with a single expression
Don't know how to make custom collections like Pixar, Ghibli, MCU
Haven't managed to transliterate asian titles
jebbe
Posts: 8
Joined: 25 Dec 2017, 04:54

Re: How about sharing our format expressions?

Post by jebbe »

Code: Select all

{['F:', 'G:', 'I:', 'J:', 'L:', 'V:', 'W:', 'Y:'].collect{ (it+'/Movies') as File }.sort{ a, b -> a.exists() <=> b.exists() ?: a.diskSpace <=> b.diskSpace }.last()} ({vf})\{n} ({y}){' ['+fn.replaceAll(/(?i)directors|theatrical|ultimate/,'$0 Cut').matchAll(/OPEN.MATTE|UNRATED|REMASTERED|EXTENDED|UNCUT|DIRECTORS.CUT|THEATRICAL.CUT|ULTIMATE.CUT|SPECIAL.EDITION/).join('][').upperInitial().lowerTrail()+']'} [{vf}] [{ac}{fn.match("-HD.MA.")+af}]/{n} ({y}) {vc}{" (CD$pi)"}{' '+lang}
Here is what I use and am still trying to figure out how to make it so if it finds Open.Matte or Special.Edition in the title and places it in the title, it removes the . between the two words. I can of course do it manually but unsure how to do this with the code. Most of what I use is pieces of many of peoples code here that I've Frankensteined together for my needs.
Baradhur
Posts: 10
Joined: 12 Jan 2016, 12:24

Re: How about sharing our format expressions?

Post by Baradhur »

Here is mine. I've used that one for 2 years now an all my libraries are organized following thing. My model is simple and represents exactly what I need.

Movies

Base format is

Code: Select all

Movie Categorie\Name in french (year) - (director) (VO name if different from french) [Languages] [Resolution, video code, audio codec]
Script

Code: Select all

Films/renamed/{any{genres[0]}{"Unknown"}}/ 
{any{localize.fr.n}{n}}
{(pn >= 2) ? " cd$pi" : ""} 
{"($y)"} 
- {"($director)"} 
{localize.fr.n == primaryTitle ? "" : "(${primaryTitle})"}
{"[${fn.lower().match(/- fr|- vostfr|- multi|\[fr\]|\[vostfr\]|\[multi\]|multi|vostfr/).replace('- ', '')}]"} 
{allOf{"$vf"}{"$vc"}{"$ac"}}
Before

Code: Select all

The.Invisible.Man.2020.MULTi.TRUEFRENCH.1080p.HDLight.x264.AC3-EXTREME.mkv
After

Code: Select all

renamed\Thriller\Invisible Man (2020) - (Leigh Whannell) (The Invisible Man) [multi] [1080p, x264, AC3]

Series
base format is

Code: Select all

TV show\TV Show Season Number\TV Show - SxE - Episode name [languages] [resolution] [codes]
Script

Code: Select all

Renamed/{n}/{n} Saison {s.pad(2)}/{n} - {sxe} - {t} {"[vostfr]"} {"[$vf]"} {allOf{"$vc"}{"$ac"}}
Before

Code: Select all

Brooklyn.Nine-Nine.S07E01.MULTi.720p.WEB.H264-CiELOS.mkv
After

Code: Select all

Renamed\Brooklyn Nine-Nine\Brooklyn Nine-Nine Saison 07\Brooklyn Nine-Nine - 7x01 - Manhunter [vostfr] [720p] [AVC, AAC].mkv
xaeiou
Posts: 15
Joined: 22 Oct 2019, 06:24

Re: How about sharing our format expressions?

Post by xaeiou »

Here is my format expression replacing characters illegal on the Windows filesystem with similar looking unicode characters. I don't use Windows, but I do share files from my Linux NAS via samba - this format is necessary for the samba clients to see the filenames correctly, otherwise they will be truncated to 8 character DOS format and are usually impossible to recognise.

It's also possible to have the fileserver make this translation, but I prefer to have filebot do it during renaming then I never have to worry about it again.

This expression includes a prefix with all the replaced characters so you can see how they look on your system font.

Thanks to rednoah for helping me simplify the syntax for this expression.

Code: Select all

'<>:"/\\|?*'.replace(
	'<' : '﹤',
	'>' : '﹥',
	':' : 'ː',
	'"' : '“',
	'/' : '⁄',
	'|' : '⼁',
	'?' : '?',
	'*' : '﹡',
	'\\': '∖'
)
WhatTimeDayPlace
Posts: 16
Joined: 05 Aug 2021, 09:42

Re: How about sharing our format expressions?

Post by WhatTimeDayPlace »

Movies with localized title + original and alternative titles

I want to keep movie files
  • in a Plex-compatible format
  • with the localized title leading.
  • In addition the original title should be added in square brackets.
  • If the local title is equal to the original title, then the original title can be dropped.
  • Alternative titles are desirable, too, but only local ones. I don't want all alternative titles world-wide.
In my case "local" is German. So desired example outcomes look like this:
  • Verfluchtes Amsterdam (1988) [Amsterdamned]
  • Wer Gewalt sät... (1971) [Straw Dogs]
  • Lost in Space (1998)
  • Dark Planet / Rebellion (2009) [Obitaemyy Ostrov. Skhvatka, The Inhabited Island 2 / Rebellion]
I lack rule programming skills. Thankfully @rednoah provided the following, which works well for me:

Code: Select all

{ny} { allOf{ primaryTitle }{ localize.en.n }.joiningDistinct(', ', '[', ']'){ n.contains(it) ? null : it } }
Issues I still see are mostly related to shortcomings in TMDB. So that is not related to FileBot or the formatting rule.

The original thread is here: viewtopic.php?f=6&t=12755
SnakeBonD
Posts: 9
Joined: 23 Jan 2022, 15:09

Re: How about sharing our format expressions?

Post by SnakeBonD »

Hi,
For my first message, I would like to thank the FileBot developers for this application, as well as all members of this forum for their sharing of examples. ;)
I spent a lot of time in this forum, because there are many ideas to find a solution for each way to rename media files. :idea:

Here is the way I rename my media files:

MOVIES:
For movies I wanted to classify them in the following order:
By studio (Marvel, Disney, Dreamworks, etc.), by Collection or by genre/
the title of the movie in my language, then in the original language if existing, the year, rating, if audio is not french and have subtitle = [VOSTFR] not subtitle=[VO], resolution and audio channels.

exemple:
_MOVIES\COLLECTION\JAMES─BOND─007\Goldeneye [1995] [6.9★] [tt0113189][HD][5.1].mkv
_MOVIES\GENRE\Action\Sky Hunter [2017] (空天猎) [7.2★] [tt6908536][VO][SD][5.1].mkv
_MOVIES\STUDIO\MARVEL\Avengers L'ère D'ultron [2015] (Avengers Age Of Ultron) [7.3★] [tt2395427][VOSTFR][Full HD][5.1].mkv

Code: Select all

/_MOVIES/
{any
	{ 
	info.productionCompanies*.match(
		/Marvel/ : 'STUDIO/MARVEL',
		/Lucasfilm/ : 'STUDIO/STAR─WARS',
		/DC / : 'STUDIO/DC─COMICS',
		/Disney/ : 'STUDIO/DISNEY',
		/Pixar/ : 'STUDIO/PIXAR',
		/Dreamworks/ : 'STUDIO/DREAMWORKS',
		/Studio Ghibli/ : 'STUDIO/STUDIO─GHIBLI'
		).find()
	}	
	
	{ 'COLLECTION/'+collection
	.replaceFirst(/^(?i)(The)\s(.+)/, /$2, $1/)
	.replaceFirst(/^(?i)(Collection of the)\s(.+)/, /$2 Collection/)
	.replaceAll(/ - Saga/, "")
	.replaceAll(/ Collection/, "")
	.replaceAll(/Saga Collection/, "")
	.replaceAll(/[`´‘’ʻ""“”]/, "'")
	.replaceAll(/[:*?"<>|?]/)
	.replaceAll(/[*\s]+/, "─")
	.upper()
	}
	
	{
	def genreOrder = ['Anilation': 1, 'Comedy': 2, 'Horror': 3, 'Science-Fiction': 4, 'Adventure': 5, 'Romance': 6, 'Drama': 7, 'Action': 8].withDefault{ 100 }
	'GENRE/'+genres.toSorted{ genreOrder[it] }[0]
	}
}/

{
	norm = {
		it
		.upperInitial()
		.lowerTrail()
		.replaceTrailingBrackets()
		.replaceAll(/[`´‘’ʻ""“”]/, "'")
		.replaceAll(/[:*?"<>|?]/)
		.replaceAll(':', 'ː')
		.replaceAll(/[?]/, "?")
	}
	; norm(n)
} 
[{y}] 
{if (norm(n) != norm(primaryTitle)) ' ('+norm(primaryTitle)+')'} 
{" ["+rating+"★]"}
{" ["+imdbid+"]"}
{'fr' in text.language ? '[VOSTFR]' : 'VO'}
{vf == /2160p/ ? '[4K]' : vf =~ /1080p/ ? '[Full HD]' : vf =~ /720p/ ? '[HD]' : '[SD]'}[{channels}]
TV SHOW:

For the Series, I classified them by the name of the series + year + number of seasons + number of episodes /
Sub folders with 1 folder by season + number episodes /
Title Serie + Name Episode + if audio is not french and have subtitle = [VOSTFR] not subtitle=[VO], resolution and audio channels.

exemple:
_SERIES\L'AGENCE TOUS RISQUES [1983] [5 Saison, 98 Episodes]\The A-Team [Saison 05-13 épisodes]\L'Agence Tous Risques [1983] - S05E01 - Dishpan Man [SD][2.0].mp4

Code: Select all

/_SERIES/
{
	norm = {
		it
		.upper()
		.replaceTrailingBrackets()
		.replaceAll(/[`´‘’ʻ""“”]/, "'")
		.replaceAll(/[:*?"<>|?]/)
		.replaceAll(':', 'ː')
		.replaceAll(/[?]/, "?")
		.replaceAll(/[*\s]+/, " ")
	}; norm(n)
} [{y}] [{episodelist.season.max()} Saison, {episodelist.count{ it.episode }} Episodes]/
/{localize.english.n.replaceAll(/[!?.]+$/).replaceAll(/[`´‘’ʻ""“”]/, "'").replaceAll(/[:*?"<>|?]/).upperInitial().replaceTrailingBrackets().lowerTrail().replacePart(', Part $1')} 
[Saison {s.pad(2)}-{episodelist.count{ it.episode && it.season == s }} épisodes]/

{
	norm = {
		it
		.upperInitial()
		.replaceTrailingBrackets()
		.replaceAll(/[`´‘’ʻ""“”]/, "'")
		.replaceAll(/[:*?"<>|?]/)
		.replaceAll(':', 'ː')
		.replaceAll(/[?]/, "?")
		.replaceAll(/[*\s]+/, " ")
	}; norm(n)
} [{y}] 

- {s00e00} - {localize.english.t.replaceAll(/[!?.]+$/).replaceAll(/[`´‘’ʻ""“”]/, "'").replaceAll(/[:*?"<>|?]/).lowerTrail().replacePart(', Part $1')} 
{'fr' in text.language ? '[VOSTFR]' : '[VO]'}
{vf == /2160p/ ? '[4K]' : vf =~ /1080p/ ? '[Full HD]' : vf =~ /720p/ ? '[HD]' : '[SD]'}[{channels}]
MUSIC:
For the music I treat them before with musicbrainz, then with mp3tag, then with Filebot.
I classify them in files according to:
File Format (if MP3 -> _MP3 _) / Genre (if no kind -> _No_Genre _) / Artist / Album / Artist - Title [Bitrate] .ext

exemple:
_MUSIC\_MP3_\_NO_GENRE_\ACDC\Acdc - Tnt [128 kbps].mp3
_MUSIC\_MP3_\SERTANEJO\LEANDRO E LEONARDO\TE AMO DEMAIS\Leandro E Leonardo - 002 - Tudo Me Lembra Você [192 kb s].mp3
_MUSIC\_FLAC_\HEAVY METAL\METALLICA\ONE OF 282\Metallica - 001 - Of Wolf And Man [1 048 kb s].flac

Code: Select all

/_MUSIC/{'_'+ext.upper()+'_'}/
{any
	{genre
	.tokenize(',')
	.first()
	.replace(':' : 'ː')
	.replaceAll(/[`´‘’ʻ""“”]/, "")
	.replaceAll(/[.:*?"<>|?]/)
	.replaceAll(/&/,"and")
	.replaceAll(/#/,"number")
	.replaceTrailingBrackets()
	.lowerTrail()
	.upper()
	}
	{'_NO_GENRE_'}
}/
{
	artist
	.replace(':' : 'ː')
	.replaceAll(/[`´‘’ʻ""“”]/, "")
	.replaceAll(/[.:*?"<>|?]/)
	.replaceAll(/&/,"and")
	.replaceAll(/#/,"number")
	.replaceTrailingBrackets()
	.lowerTrail()
	.upper()
}/

{
	album
	.replaceAll(/&/,"and")
	.replaceAll(/#/,"number")
	.replace(':' : 'ː')
	.replaceAll(/[`´‘’ʻ""“”]/, "")
	.replaceAll(/[.:*?"<>|?]/)
	.replaceTrailingBrackets()
	.lowerTrail()
	.upper()
}
/
{
	artist
	.replace(':' : 'ː')
	.replaceAll(/[`´‘’ʻ""“”]/, "")
	.replaceAll(/[.:*?"<>|?]/)
	.replaceAll(/&/,"and")
	.replaceAll(/#/,"number")
	.replaceTrailingBrackets()
	.lowerTrail()
	.upperInitial()
}
{any
	//{media.'part/position_total' == null ? null : '/CD ' + media.'part/position'}
	{' - '+pi.pad(3)+' - '}
	{' - '}
}

{
	t
	.replace(':' : 'ː')
	.replaceAll(/[`´‘’ʻ""“”]/, "")
	.replaceAll(/[.:*?"<>|?]/)
	.replaceAll(/&/,"and")
	.replaceAll(/#/,"number")
	.replaceTrailingBrackets()
	.lowerTrail()
	.upperInitial()
} 
[{audio[0].bitratestring.replace('/', 'p')}]
Last edited by SnakeBonD on 23 Jan 2022, 16:10, edited 1 time in total.
cyberdoggy
Posts: 41
Joined: 03 Sep 2016, 21:27

MY Script I have been working on for years and is pretty close to being perfect for me!

Post by cyberdoggy »

Code: Select all

{fn=~/2160p/?'Movies 4K':'Movies'} {vc=~/HEVC|265|AV1/?(vc=='AV1'?'(AV1)':'(x265)'):'(x264)'}/{
  norm = {
    it.colon(' - ').tr('*?|', ' !-')
      .asciiQuotes()
      .replaceAll(/\b(?i)[IVX]+\b/, { it.upper() })
      .replaceAll(/\b[0-9](?i:st|nd|rd|th)\b/, { it.lower() })
      .replaceAll(/(Collection) of the (.+)/, /$2 $1/)
      .replaceAll(/(Saga) Collection/, /$1/)
      .replaceAll(/^(?i)(The|A|An|Der|Die|Das) (.+)/, /$2, $1/)
  };
  path = allOf { norm(collection) } { norm(n) }.join('/');
  path[0].replaceAll(/\W|\d/, '#') + '/' + path}
  {norm(n) != norm(primaryTitle) ? ' (' + primaryTitle + ')' : null
}{ fn =~ /3D|3-D/ ? ' 3D' : null} ({y}) {[aco.match(/ATMOS/) ? 'Atmos' : null]}
{tags*.toUpperCase()} {["$group"]}/
{ allOf {n.asciiQuotes().removeAll(/[,!]/)}{fn =~ /3D|3-D/ ? '3D' : null} {".$y"}{edition}{tags*.toUpperCase()}{'Part'+pi}{".$vf"}{".$HD"}
{ fn.match(/(?-i:ATVP|AMZN|DCU|DSNP|DSNY|Disney[+]|DisneyPlus|HBO|HULU|NF|SUBBED|Encore.Edition|Colorized|B&W|HQ)/) }
{if (bitdepth >= 10) 'HDR10'}{(hdr == 'Dolby Vision' || hdr == 'Dovi') ? '_DV' : ''}
{ HD == 'UHD' ? '4K' : '' }{".$vs"}
 {vc =~ /HEVC|265|AV1/ ? (vc =~ /AV1/ ? 'AV1' : 'x265') : 'x264'}
{"$ac"}{aco.match(/ATMOS/)}{af == 8 ? 'DD+7.1CH' : af == 7 ? '6.1CH': af == 6 ? 'DD.5.1CH': af == 3 ? '2.1CH': af == 2 ? '2.0CH': (af as int) + 'CH'}.join('.').space('.')
}{'-'+group}
First I want to thank @rednoah for all the patience and Chat GPT for corrections.

Let's break down each section of the code and its purpose:

J:\{fn=~/2160p/?'Movies 4K':'Movies'}: This sets the initial file path to either "Movies" or "Movies 4K", depending on whether the file has a resolution of 2160p (4K) or not.

{vc=~/HEVC|265|AV1/?(vc=='AV1'?'(AV1)':'(x265)'):'(x264)'}: This assigns the video codec of the file to either "(AV1)", "(x265)", or "(x264)", depending on whether the codec matches "AV1", "265", or "HEVC". If the codec doesn't match any of those, it defaults to "(x264)".

{ norm = {...} }: This defines a function named "norm" that normalizes the movie title by replacing certain characters and formatting the title in a consistent way. The function is used later in the script to format both the collection and movie titles.

{ path = allOf { norm(collection) } { norm(n) }.join('/') }: This creates the file path for the movie by joining together the normalized collection and movie titles with forward slashes.

{ norm(n) != norm(primaryTitle) ? ' (' + primaryTitle + ')' : null }: If the normalized movie title does not match the normalized primary title, this section appends the primary title in parentheses to the file name. If the titles match, this section returns null.

{ fn =~ /3D|3-D/ ? ' 3D' : null }: If the file name includes "3D" or "3-D", this section appends " 3D" to the file name. If not, it returns null.

({y}): This appends the year of release to the file name in parentheses.

{[aco.match(/ATMOS/) ? 'Atmos' : null]}: If the audio codec contains "ATMOS", this section appends "Atmos" to the file name. If not, it returns null.

{tags*.toUpperCase()}: This adds any tags included in the file name in uppercase letters.

{["$group"]}: This appends the group releasing the file in square brackets.

{ allOf {...} }: This defines a new function that formats several attributes of the file name.

{n.asciiQuotes().removeAll(/[,!]/)}: This removes commas and exclamation points from the movie title and replaces any double quotes with single quotes.

{fn =~ /3D|3-D/ ? '3D' : null}: If the file name includes "3D" or "3-D", this section appends "3D" to the file name. If not, it returns null.

{".$y"}: This appends the year of release to the file name preceded by a period.

{edition}: This appends the edition of the movie, such as "Director's Cut" or "Extended Edition".

{tags*.toUpperCase()}: This adds any tags included in the file name in uppercase letters.

{'Part'+pi}: This appends the part number of a multi-part movie, such as "Part 1" or "Part 2".

{".$vf"}: This appends the video format of the movie, such as "1080p" or "2160p".

{".$HD"}: This appends the resolution

{tags*.toUpperCase()}

This section converts all the elements in the "tags" array to uppercase letters. The "tags" array is a property of the media file that contains various tags or labels that describe the file, such as the genre, language, or content rating.

{["$group"]}

This section adds the value of the "$group" variable to the end of the path. The "$group" variable is a user-defined variable that can be set to any value before running the script. It is useful for grouping related files together.

/

This section adds a forward slash character to the end of the path, separating it from the filename.

{ allOf {n.asciiQuotes().removeAll(/[,!]/)}

This section creates a new string by applying several transformations to the "n" variable. First, it replaces any curly or straight quotes with ASCII quotes. Then it removes any commas or exclamation marks from the string.

{fn =~ /3D|3-D/ ? '3D' : null}

This section adds the string "3D" to the filename if the "fn" variable contains the substring "3D" or "3-D". Otherwise, it returns null.

{".$y"}

This section adds a period character followed by the value of the "y" variable to the filename. The "y" variable is a property of the media file that contains the release year.

{edition}

This section adds the value of the "edition" variable to the filename. The "edition" variable is a user-defined variable that can be set to any value before running the script. It is useful for distinguishing different versions of the same file.

{tags*.toUpperCase()}

This section converts all the elements in the "tags" array to uppercase letters and adds them to the filename.

{'Part'+pi}

This section adds the string "Part" followed by the value of the "pi" variable to the filename. The "pi" variable is a user-defined variable that can be set to any value before running the script. It is useful for identifying which part of a multi-part file this particular file belongs to.

{".$vf"}

This section adds a period character followed by the value of the "vf" variable to the filename. The "vf" variable is a property of the media file that contains the video format.

{".$HD"}

This section adds a period character followed by the value of the "HD" variable to the filename. The "HD" variable is a property of the media file that contains the video resolution.

{ fn.match(/(?-i:ATVP|AMZN|DCU|DSNP|DSNY|Disney[+]|DisneyPlus|HBO|HULU|NF|SUBBED|Encore.Edition|Colorized|B&W|HQ)/) }

This section adds various labels to the filename based on the value of the "fn" variable. These labels indicate the source of the file, whether it has been colorized or is in black and white, whether it is a high-quality version, and other relevant information.

{if (bitdepth >= 10) 'HDR10'}

This section adds the string "HDR10" to the filename if the "bitdepth" variable is greater than or equal to 10. The "bitdepth" variable is a property of the media file that contains the bit depth of the video.

{(hdr == 'Dolby Vision' || hdr == 'Dovi') ? '_DV' : ''}

This section adds the string "_DV" to the filename if the "hdr" variable is equal to "Dolby Vision" or "Dovi". The "hdr"

{ HD == 'UHD' ? '4K' : '' }: This section checks if the variable HD is equal to 'UHD' (which stands for ultra high definition) and if it is, it returns '4K'. Otherwise, it returns an empty string.

{".$vs"}: This section simply returns the variable vs with a period before it.

{vc =~ /HEVC|265|AV1/ ? (vc =~ /AV1/ ? 'AV1' : 'x265') : 'x264'}: This section checks if the variable vc matches any of the regular expressions /HEVC|265|AV1/. If it does, it checks if vc matches the regular expression /AV1/ and if it does, it returns 'AV1'. Otherwise, it returns 'x265'. If vc doesn't match any of the regular expressions, it returns 'x264'.

{"$ac"}: This section simply returns the variable ac.

{aco.match(/ATMOS/)}: This section checks if the variable aco matches the regular expression /ATMOS/ and returns a boolean value.

{af == 8 ? 'DD+7.1CH' : af == 7 ? '6.1CH': af == 6 ? 'DD.5.1CH': af == 3 ? '2.1CH': af == 2 ? '2.0CH': (af as int) + 'CH'}: This section checks the value of the variable af and returns a string based on its value. If af is 8, it returns 'DD+7.1CH'. If af is 7, it returns '6.1CH'. If af is 6, it returns 'DD.5.1CH'. If af is 3, it returns '2.1CH'. If af is 2, it returns '2.0CH'. If af is any other integer, it returns the integer value followed by 'CH'.

.join('.').space('.'): This section joins all the string values returned from the previous sections with periods and then replaces spaces with periods.

Hopefully this will help all you newbies out there and maybe you might want to use the code as it is. I have self taught myself how to write this and am pretty happy with the outcome. As usual I am never really done with it I always tinker onward!
shomidamoney
Posts: 1
Joined: 07 Apr 2023, 10:42

Re: How about sharing our format expressions?

Post by shomidamoney »

Let me give you a bit of context. For me whenever I get a new file, I put it into a sorting hat folder to rename and sort through the files, from there I put it into the correct places; i.e. Movies, Collections, TV Shows, etc. folders. I have a few different presets I use depending on the situation.

These are my most commonly used.

Basically it renames the file, places it into a folder with the same name, and any other parent folders like collection/season, then places it into my sorting hat folder.

Unsorted TV Shows:

Code: Select all

Sorting Hat/{ny}/Season {s}/{ny.colon(' - ')}{s00e00} - {t.colon(' - ')}{if (edition == '')'' else (' -'+{edition})} [{if (hd == 'UHD')'4k UHD' else if (hd == 'FHD')'1080p FHD' else if (hd == 'HD')'720p HD' else if (hd == 'SD')'480p SD' else ({hd})}{if (hdr == '') '' else({','+hdr})},{acf}]
Example:
From - Breaking.Bad.S02E01.1080p.BluRay.x265-RARBG
To - Sorting Hat/Breaking Bad (2008)/Season 2/Breaking Bad (2008) S02E01 - Seven Thirty-Seven [1080p FHD,AAC5.1]

Unsorted Movies - Collection:

Code: Select all

Sorting Hat/{if (collection == '') '' else (collection.colon(' - ')+'/')}{ny.colon(' - ')}/{ny.colon(' - ')}{if (edition == '')'' else (' - '+{edition})} [{if (hd == 'UHD')'4k UHD' else if (hd == 'FHD')'1080p FHD' else if (hd == 'HD')'720p HD' else if (hd == 'SD')'480p SD' else ({hd})}{if (hdr == '') '' else({','+hdr})},{acf}]
Example:
From - Avatar.2009.EXTENDED.1080p.BluRay.x265-RARBG.mp4
To - Sorting Hat/Avatar (2009)/Avatar (2009) - Extended [1080p FHD,AAC5.1].mp4

Unsorted Movies - No Collection: (sometimes I use this if I have existing collection folders; i.e. new movie in series comes out)

Code: Select all

Sorting Hat/{ny.colon(' - ')}/{ny.colon(' - ')}{if (edition == '')'' else (' - '+{edition})} [{if (hd == 'UHD')'4k UHD' else if (hd == 'FHD')'1080p FHD' else if (hd == 'HD')'720p HD' else if (hd == 'SD')'480p SD' else ({hd})}{if (hdr == '') '' else({','+hdr})},{acf}]
Example:
From - Avatar.The.Way.of.Water.2022.2160p.WEB-DL.DDP5.1.Atmos.DV.HDR10.HEVC-CMRG.mkv
To - Sorting Hat/Avatar - The Way of Water (2022)/Avatar - The Way of Water (2022) [4k UHD,Dolby Vision,DDPDA5.1].mkv

There's prolly some things I should change but so far this seems to be good. I also have some other simple renaming ones in case I need to do an overhaul of renaming where it keeps the files in its place and just renames it.

Please provide me with any feedback, good or bad.
DocShaker
Posts: 5
Joined: 13 Jun 2021, 21:32

Re: How about sharing our format expressions?

Post by DocShaker »

Movies:

Movies in Their Own Folders

Asterix & Obelix The Middle Kingdom (2023) {tmdb-643215}\Asterix & Obelix The Middle Kingdom (2023) {tmdb-643215} [1080p WEB-DL AVC] [WDYM].mkv
Twin Dragons (1992) {tmdb-18764} {edition-International Cut}\Twin Dragons (1992) {tmdb-18764} {edition-International Cut} [1080p BluRay REMUX AVC] [FraMeSToR].mkv
Twin Dragons (1992) {tmdb-18764} {edition-Theatrical Cut}\Twin Dragons (1992) {tmdb-18764} {edition-Theatrical Cut} [1080p BluRay HYBRID REMUX AVC] [FraMeSToR].mkv
Cult of Chucky (2017) {tmdb-393345}\Cult of Chucky (2017) {tmdb-393345} [2160p BluRay REMUX Dolby Vision HEVC] [FraMeSToR].mkv

Code: Select all

{folder}/{n.validateFileName()} ({y}) {" {tmdb-$id}"} { "{edition-${tags[0]}}" }/{n.validateFileName()} ({y}) {" {tmdb-$id}"} { "{edition-${tags[0]}}" } {[fn.match(/REPACK/)]} {[fn.match(/PROPER/)]} [{vf} {vs.replace('Bluray','BluRay').replace('Blu-ray','BluRay').replace('DVD-R','DVD')} {fn.match(/Hybrid/)} {fn.match(/REMUX/)} {hdr} {vcf.replace('MPEG Video','MPEG')}] [{ any{ fn.match(/^\[(.*?)\]/) }{ fn.match(/\[([^\[\]]+)\]+/) }{ fn.match(/[-]([^-]+)$/) }{ group } }]

Movies with no folders:

Asterix & Obelix The Middle Kingdom (2023) {tmdb-643215} [1080p WEB-DL AVC] [WDYM].mkv
Twin Dragons (1992) {tmdb-18764} {edition-International Cut} [1080p BluRay REMUX AVC] [FraMeSToR].mkv
Twin Dragons (1992) {tmdb-18764} {edition-Theatrical Cut} [1080p BluRay HYBRID REMUX AVC] [FraMeSToR].mkv
Cult of Chucky (2017) {tmdb-393345} [2160p BluRay REMUX Dolby Vision HEVC] [FraMeSToR].mkv

Code: Select all

{n.validateFileName()} ({y}) {" {tmdb-$id}"} { "{edition-${tags[0]}}" } {[fn.match(/REPACK/)]} {[fn.match(/PROPER/)]} [{vf} {vs.replace('Bluray','BluRay').replace('Blu-ray','BluRay').replace('DVD-R','DVD')} {fn.match(/Hybrid/)} {fn.match(/REMUX/)} {hdr} {vcf.replace('MPEG Video','MPEG')}] [{ any{ fn.match(/^\[(.*?)\]/) }{ fn.match(/\[([^\[\]]+)\]+/) }{ fn.match(/[-]([^-]+)$/) }{ group } }]

Series Anime/TV with series and season folders:

Series with episode title:

My Unique Skill Makes Me OP Even at Level 1 (2023)\Season 01\My Unique Skill Makes Me OP Even at Level 1 (2023) S01E01 He's a Human That Was Dropped by a Slime [1080p WEB-DL AVC] [ZR].mkv
The Queen's Gambit (2020)\Season 01\The Queen's Gambit (2020) S01E01 Openings [2160p WEB-DL Hybrid Dolby Vision HEVC] [HONE].mkv
Squid Game (2021)\Season 01\Squid Game (2021) S01E01 Red Light, Green Light [2160p WEB-DL HDR10 HEVC] [HBO].mkv
Kuromukuro (2016)\Season 01\Kuromukuro (2016) S01E01 A Rain of Ogres from the Sky [1080p REMUX AVC] [FraMeSToR].mkv

Code: Select all

{folder}/{n.validateFileName()} ({y})/Season {s.pad(2)}/{n.validateFileName()} ({y}) {s00e00} {t.validateFileName()} { "{edition-${tags[0]}}" } {[fn.match(/REPACK/)]} {[fn.match(/PROPER/)]} [{vf} {vs.replace('Bluray','BluRay').replace('Blu-ray','BluRay').replace('DVD-R','DVD')} {fn.match(/Hybrid/)} {fn.match(/REMUX/)} {hdr} {vcf.replace('MPEG Video','MPEG')}] [{ any{ fn.match(/^\[(.*?)\]/) }{ fn.match(/\[([^\[\]]+)\]+/) }{ fn.match(/[-]([^-]+)$/) }{ group } }]

Series without episode title:

My Unique Skill Makes Me OP Even at Level 1 (2023)\Season 01\My Unique Skill Makes Me OP Even at Level 1 (2023) S01E01 [1080p WEB-DL AVC] [ZR].mkv
The Queen's Gambit (2020)\Season 01\The Queen's Gambit (2020) S01E01 [2160p WEB-DL Hybrid Dolby Vision HEVC] [HONE].mkv
Squid Game (2021)\Season 01\Squid Game (2021) S01E01 [2160p WEB-DL HDR10 HEVC] [HBO].mkv
Kuromukuro (2016)\Season 01\Kuromukuro (2016) S01E01 [1080p REMUX AVC] [FraMeSToR].mkv

Code: Select all

{folder}/{n.validateFileName()} ({y})/Season {s.pad(2)}/{n.validateFileName()} ({y}) {s00e00} { "{edition-${tags[0]}}" } {[fn.match(/REPACK/)]} {[fn.match(/PROPER/)]} [{vf} {vs.replace('Bluray','BluRay').replace('Blu-ray','BluRay').replace('DVD-R','DVD')} {fn.match(/Hybrid/)} {fn.match(/REMUX/)} {hdr} {vcf.replace('MPEG Video','MPEG')}] [{ any{ fn.match(/^\[(.*?)\]/) }{ fn.match(/\[([^\[\]]+)\]+/) }{ fn.match(/[-]([^-]+)$/) }{ group } }]


Series Anime/TV with no series and season folders:

Series with episode title:

My Unique Skill Makes Me OP Even at Level 1 (2023) S01E01 He's a Human That Was Dropped by a Slime [1080p WEB-DL AVC] [ZR].mkv
The Queen's Gambit (2020) S01E01 Openings [2160p WEB-DL Hybrid Dolby Vision HEVC] [HONE].mkv
Squid Game (2021) S01E01 Red Light, Green Light [2160p WEB-DL HDR10 HEVC] [HBO].mkv
Kuromukuro (2016) S01E01 A Rain of Ogres from the Sky [1080p REMUX AVC] [FraMeSToR].mkv

Code: Select all

{n.validateFileName()} ({y}) {s00e00} {t.validateFileName()} { "{edition-${tags[0]}}" } {[fn.match(/REPACK/)]} {[fn.match(/PROPER/)]} [{vf} {vs.replace('Bluray','BluRay').replace('Blu-ray','BluRay').replace('DVD-R','DVD')} {fn.match(/Hybrid/)} {fn.match(/REMUX/)} {hdr} {vcf.replace('MPEG Video','MPEG')}] [{ any{ fn.match(/^\[(.*?)\]/) }{ fn.match(/\[([^\[\]]+)\]+/) }{ fn.match(/[-]([^-]+)$/) }{ group } }]

Series without episode title:

My Unique Skill Makes Me OP Even at Level 1 (2023) S01E01 [1080p WEB-DL AVC] [ZR].mkv
The Queen's Gambit (2020) S01E01 [2160p WEB-DL Hybrid Dolby Vision HEVC] [HONE].mkv
Squid Game (2021) S01E01 [2160p WEB-DL HDR10 HEVC] [HBO].mkv
Kuromukuro (2016) S01E01 [1080p REMUX AVC] [FraMeSToR].mkv

Code: Select all

{n.validateFileName()} ({y}) {s00e00} { "{edition-${tags[0]}}" } {[fn.match(/REPACK/)]} {[fn.match(/PROPER/)]} [{vf} {vs.replace('Bluray','BluRay').replace('Blu-ray','BluRay').replace('DVD-R','DVD')} {fn.match(/Hybrid/)} {fn.match(/REMUX/)} {hdr} {vcf.replace('MPEG Video','MPEG')}] [{ any{ fn.match(/^\[(.*?)\]/) }{ fn.match(/\[([^\[\]]+)\]+/) }{ fn.match(/[-]([^-]+)$/) }{ group } }]
619annamalc
Posts: 5
Joined: 06 Jan 2024, 00:46

Re: How about sharing our format expressions?

Post by 619annamalc »

I've been using Filebot for about 3 years now, and it has been a game changer with organizing files. I'm still learning and messing with it, and the team here is amazing with helping and explaining. I have used a combination of Plex, Embi, and Jellyfin to host different files, and these formats have not caused issues with any of them. After reading through many forums, I have compiled the following formats which have helped me tremendously:

Movie Code v1. This uses TMDB Collections to organize movies into folders, and adds the movie version tags to folder and file name (i.e. remastered, extended, unrated, etc.):

Format: Select all

{collection+'/'}{n} ({y}) {' (' + fn.matchAll(/extended|uncensored|uncut|directors[ ._-]cut|remastered|unrated|special[ ._-]edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[.]/, " ") + ')'} {"{imdb-$imdbid}"} / {n} ({y}) {"[$vf $vc $ac $af]"}{"{edition-${tags.first()}}"}{subt}

Movie Code v2. This code uses the same code as v1, but will add Language tags to the folder name based on the number of audio streams found in the file (i.e. more than 3 streams = Multi Audio, 2 streams = Dual Audio, 1 stream that is not English will use ISO3 tags, ex. JPN, KOR, RUS). I use this for Foreign and Anime:

Format: Select all

{collection+'/'} {n} ({y}) {' (' + fn.matchAll(/extended|uncensored|uncut|directors[ ._-]cut|remastered|unrated|special[ ._-]edition/)*.upperInitial()*.lowerTrail().sort().join(', ').replaceAll(/[.]/, " ") + ')'} {"{imdb-$imdbid}"} {audioLanguages.size() > 2 ? ' (Multi Audio)' : audioLanguages.size() > 1 ? ' (Dual Audio)' : audioLanguages =~ /eng/ ? null : audioLanguages.ISO3.joining(', ', ' (', ')').upper()} / {n} ({y}) {"[$vf $vc $ac $af]"}{" {edition-${tags.first()}}"}{subt}

TV Code v1. Basic code which will generate show name, season folder, and episode format.

Format: Select all

{n} ({y}) {"{tmdb-$tmdbid}"}/Season {s}/{s00E00} - {t} {"[$vf $vc $ac $af]"}{subt}

TV Code v2. This uses the same base code as v1, but I added the Language tags. This has been very helpful with Foreign and Anime.

Format: Select all

{n} ({y}) {"{tmdb-$tmdbid}"} {audioLanguages.size() > 2 ? ' (Multi Audio)' : audioLanguages.size() > 1 ? ' (Dual Audio)' : audioLanguages =~ /eng/ ? null : audioLanguages.ISO3.joining(', ', ' (', ')').upper()} / Season {s}/{s00E00} - {t} {"[$vf $vc $ac $af]"}{subt}
Post Reply