I’ve created a script using AI that, when run, looks for filenames longer than a given value, then renames and reduces them to the same given value. The script then monitors the directory for new files and reruns the renaming function on the new files only.
Additionally, for specific file types, videos in this case, it also moves the files older than a certain age (in minutes) to another directory.
Example Filename: ThisFileHasOver"40"Characters:WhichIsKindaRidiculouslyLongAndItEvenHasADateAndTimeAtTheEndOfIt_2024-07-23-21-14-41.jpeg
Renamed Filename: ThisFileHasOver40…_2024-07-23-21-14-41.jpeg
For my purposes, it keeps the last 20 characters and truncates the middle, while reducing the filename to 40 characters, excluding the file extension. It also removes most punctuation.
It is specific to media files, but with a little editing, it can be used for any files you wish.
All you would need to do is add the file extensions you want to the list(s).
I created it because some website media files download with ridiculously long filenames, which can sometimes cause issues with moving files or saving files in programs like GIMP.
Disclaimer: I’ve tested it multiple times on 5 duplicated folders with over 1500 images and videos. However, I am not a programmer nor a regular scripter, so this script is provided as is. If you decide to try it, you should first test it on a duplicated folder yourself before employing it on any other directory. Even if it works 99.9997% of the time and on one occassion it destroys your home or root directory (it cannot get to root unless you explicitly run it as root in a root directory, but still), I am not responsible. Use at your own risk!
The Script
#!/bin/bash
# Configuration variables
MONITOR_DIR="/path/to/monitor/directory/" # Directory to monitor
DEST_DIR="/path/to/destination/directory/" # Directory to move files to
MIN_AGE=5940 # Minimum age of files in seconds before moving (99 minutes)
CHECK_INTERVAL=60 # How often to check the directory in seconds (1 minute)
# List of image and video file extensions
IMAGE_EXTENSIONS=("jpg" "jpeg" "png" "gif" "bmp" "jpe" "webp" "avif" "exr" "psd" "hdr" "jxl" "apng" "tif" "tiff" "tga" "raw" "heic" "heif" "svg" "eps")
VIDEO_EXTENSIONS=("mp4" "avi" "mov" "mkv" "wmv" "webm" "m4v" "flv")
# Function to truncate filenames
truncate_filename() {
local filename="$1"
local extension="${filename##*.}"
local base="${filename%.*}"
if [[ ${#base} -gt 40 ]]; then
local last20="${base: -20}"
echo "${base:0:17}...${last20}.${extension}"
else
echo "$filename"
fi
}
# Function to get a unique filename
get_unique_filename() {
local base_path="$1"
local filename="$2"
local extension="${filename##*.}"
local base="${filename%.*}"
local counter=1
local new_filename="$filename"
while [[ -e "$base_path/$new_filename" ]]; do
new_filename="${base}_${counter}.${extension}"
((counter++))
done
echo "$new_filename"
}
# Function to move files
move_files() {
for file in "$MONITOR_DIR"/*; do
if [[ -f "$file" ]]; then
filename=$(basename "$file")
extension="${filename##*.}"
# Check if the file is a video and meets the conditions
if [[ " ${VIDEO_EXTENSIONS[@]} " =~ " ${extension,,} " ]]; then
# Check if the file is older than MIN_AGE seconds
if [[ $(($(date +%s) - $(stat -c %Y "$file"))) -ge $MIN_AGE ]]; then
# Get a unique filename for the destination
new_filename=$(get_unique_filename "$DEST_DIR" "$filename")
# Move the file
mv "$file" "$DEST_DIR/$new_filename"
echo "Moved $filename to $DEST_DIR/$new_filename"
fi
fi
fi
done
}
# Function to monitor and rename files
monitor_directory() {
while true; do
for file in "$MONITOR_DIR"/*; do
if [[ -f "$file" ]]; then
filename=$(basename "$file")
extension="${filename##*.}"
base="${filename%.*}"
# Check if the file is an image or video and meets the conditions
if [[ " ${IMAGE_EXTENSIONS[@]} " =~ " ${extension,,} " || " ${VIDEO_EXTENSIONS[@]} " =~ " ${extension,,} " ]]; then
if [[ ${#filename} -gt 40 && ! "$filename" =~ \.\.\. ]]; then
# Check if the file is not older than MIN_AGE seconds
if [[ $(($(date +%s) - $(stat -c %Y "$file"))) -le $MIN_AGE ]]; then
new_filename=$(truncate_filename "$filename")
if [[ "$new_filename" != "$filename" ]]; then
mv "$file" "$MONITOR_DIR/$new_filename"
echo "Renamed $filename to $new_filename"
fi
fi
fi
fi
fi
done
# Call the move_files function
move_files
# Sleep for CHECK_INTERVAL seconds
sleep $CHECK_INTERVAL
done
}
# Start monitoring the directory
monitor_directory
A More Detailed Explanation (With Instructions):
Certainly! Here’s a detailed explanation and usage instructions for the script:
Script Explanation
This Bash script is designed to monitor a specific directory for image and video files, perform two main operations:
- Rename long filenames
- Move video files to a destination directory
Key Components:
-
Configuration Variables:
MONITOR_DIR
: The directory to be monitoredDEST_DIR
: The directory where video files will be movedIMAGE_EXTENSIONS
andVIDEO_EXTENSIONS
: Lists of file extensions to processMIN_AGE
: Minimum age (in minutes) of files before they’re movedCHECK_INTERVAL
: How often the script checks the directory (in minutes)
-
Main Functions:
truncate_filename()
: Shortens long filenamesget_unique_filename()
: Ensures unique filenames in the destination directorymove_files()
: Moves video files to the destination directorymonitor_directory()
: Main loop that oversees renaming and moving operations
Workflow:
- The script continuously monitors the specified directory.
- It renames files longer than 40 characters, truncating them with “…” in the middle.
- Video files older than the specified minimum age are moved to the destination directory.
- If a file with the same name exists in the destination, the script adds a numeric suffix to ensure uniqueness.
Usage Instructions
-
Setup:
- Save the script with a
.sh
extension (e.g.,media_manager.sh
). - Make the script executable:
chmod +x media_manager.sh
- Save the script with a
-
Configuration:
- Open the script in a text editor.
- Modify the following variables according to your needs:
MONITOR_DIR
: Set this to the directory you want to monitorDEST_DIR
: Set this to where you want to move the video filesMIN_AGE
: Adjust if you want to change how old files should be before movingCHECK_INTERVAL
: Change if you want to alter how often the script checks for files
-
Running the Script:
- Open a terminal and navigate to the directory containing the script.
- Run the script:
./media_manager.sh
- The script will run continuously until stopped.
-
Stopping the Script:
- To stop the script, press
Ctrl+C
in the terminal where it’s running.
- To stop the script, press
-
Running in the Background:
- To run the script in the background, use:
nohup ./media_manager.sh &
- This will allow the script to continue running even if you close the terminal.
- To run the script in the background, use:
-
Logging (Optional):
- To log the script’s output, you can redirect it to a file:
./media_manager.sh > logfile.txt 2>&1 &
- This will create a log file named
logfile.txt
in the same directory.
- To log the script’s output, you can redirect it to a file:
-
Automating Startup:
- To run the script automatically at system startup, you can either add the bash script to your startup applications or add it to your crontab.
crontab -e
- Add the following line:
@reboot /path/to/media_manager.sh
- To run the script automatically at system startup, you can either add the bash script to your startup applications or add it to your crontab.
Remember to replace /path/to/media_manager.sh
with the actual path to your script.
Notes:
- Ensure you have write permissions for both the monitored and destination directories.
- Regularly check the log file (if you’ve set up logging) to monitor the script’s activity.
- Be cautious when setting the
MIN_AGE
too low, as it might move files that are still in use.
This script provides an automated way to manage your files, keeping your directories organized by renaming long filenames and moving video files to a specified location.