So I am having this situation... I have many files in my Folder which will look like this
Iron.Man.2008.1440p.UHD.US.BluRay.x265.HDR.DD5.1-Pahe.in
Iron Man 2008.7
with bash using the regex pattern matching with BASH_REMATCH
#!/usr/bin/env bash
declare -A uniq
##: The script should be inside the directory where the video files are
for files in *; do
if [[ $files =~ ^(.*[[:digit:]]{4})\.(.+)$ ]]; then
no_space=${BASH_REMATCH[1]// /.}
uniq[$no_space]=1
all_files+=("${BASH_REMATCH[0]}")
first_part+=("${BASH_REMATCH[1]}")
fi
done
for j in "${!uniq[@]}"; do
mkdir -p "$j"
dir+=("$j")
done
for i in "${!all_files[@]}"; do
for k in "${dir[@]}"; do
if [[ ${first_part[$i]// /.} == $k ]]; then
mv -v "${all_files[$i]}" "$k"
fi
done
done
Version 2.0 which try to match all the new file format/pattern.
#!/usr/bin/env bash
declare -A uniq
for files in *; do
if [[ $files =~ ^(.*\(?[[:digit:]]{4}\)?)[\.[[:blank:]]]?(.+)$ ]]; then
no_space=${BASH_REMATCH[1]// /.}
uniq[$no_space]=1
all_files+=("${BASH_REMATCH[0]}")
first_part+=("${BASH_REMATCH[1]}")
fi
done
for j in "${!uniq[@]}"; do
mkdir -p "${j//[)(]}"
dir+=("$j")
done
for i in "${!all_files[@]}"; do
for k in "${dir[@]}"; do
if [[ ${first_part[$i]// /.} == $k ]]; then
mv -v "${all_files[$i]}" "${k//[)(]}"
fi
done
done
Just try it out for a couple of sample files and not the whole 4k files like what you have now.
also make a backup of the files just in case.
Since you also tagged this PowerShell
, here's a solution:
$sourceFolder = 'D:\Test' # where the files are now
$destination = 'D:\Movies' # where the subfolders storing the files should be created
$regex = '^(\D+[.\s]\d{4})\..*' # see explanation below
(Get-ChildItem -Path 'D:\Test' -File | Where-Object { $_.BaseName -match $regex }) |
ForEach-Object {
$subFolder = ([regex]$regex).Match($_.BaseName).Groups[1].Value -replace '\s', '.'
$targetDir = Join-Path -Path $destination -ChildPath $subFolder
# create the subfolder if it does not yet exist
if (!(Test-Path -Path $targetDir -PathType Container)) {
$null = New-Item -Path $targetDir -ItemType Directory
}
$_ | Copy-Item -Destination $targetDir
}
Regex details:
^ # Assert position at the beginning of a line (at beginning of the string or after a line break character) ( # Match the regular expression below and capture its match into backreference number 1 \D # Match a single character that is not a digit 0..9 + # Between one and unlimited times, as many times as possible, giving back as needed (greedy) [.\s] # Match a single character present in the list below # The character “.” # A whitespace character (spaces, tabs, line breaks, etc.) \d # Match a single digit 0..9 {4} # Exactly 4 times ) \. # Match the character “.” literally . # Match any single character that is not a line break character * # Between zero and unlimited times, as many times as possible, giving back as needed (greedy)