Take the 2-minute tour ×
Ask Different is a question and answer site for power users of Apple hardware and software. It's 100% free, no registration required.

Is it possible to use Automator to automatically move a subtitle file .srt to the folder where a video file with the same name is located?

Let's say I have a file ~/Videos/MyVideoFolder/my_video.avi and I download a file ~/Downloads/my_video.srt, I want it to automagically move it to ~/Videos/MyVideoFolder/.

The subtitles files are identifiable by its extension .srt, but videos can be of any type.

share|improve this question
    
automagically?? Did you invent that word? –  Buscar웃 Feb 2 at 11:43
    
When do you want that to happen? Before the download or after the download. You can specify the folder for the download so it will be there already. How does the automagical supposing to know which download belongs where? –  Buscar웃 Feb 2 at 11:46
    
I love that word "automagically" I going to use it when something I automated is to complex to explain how I did it. –  markhunte Feb 2 at 14:13

3 Answers 3

up vote 3 down vote accepted

You can use a Automator folder action workflow.

The folder action watches the downloads folder.

The Filter Finder Items filters be extension

The Applescript does the rest.

enter image description here


Applescript Code:

on run {input, parameters}
    (* video folder path *)
    set folderName to "videos:MyVideoFolder"
    set homePath to (path to home folder as text) as text
    set thepath to POSIX path of (homePath & folderName)

    (* repeat with the srt files from input*)
    repeat with i from 1 to number of items in input
        set this_item to (item i of input as text)

        (* get the file name *)
        set baseName to (do shell script "basename  " & quoted form of (POSIX path of this_item))
        (* strip the extension from the name *)
        set fileName to (do shell script "echo  " & quoted form of baseName & "  |cut -d'.' -f1")


        (*test if a Video file with the name fileName  exists in the video folder *)
        if (do shell script "/bin/test -e " & (quoted form of (thepath & "/") & fileName & ".") & "*  ; echo $?") is "0" then
            --0 = exists

            (*test if a srt file with the exact name baseName extension exists in the video folder *)
            if (do shell script "/bin/test -e " & (quoted form of (thepath & "/" & baseName)) & "  ; echo $?") is "1" then
                --1 = not exists


                (*move the scrt file *)
                do shell script " /bin/mv " & (POSIX path of this_item) & space & thepath & "/\"\""
            end if

        end if

    end repeat

end run

The code is commented to explain what it is doing.

This is an example. It works as is on my tests when a file with the correct extension is added to the watched folder. Then moves it/them to the videos folder if they do not exist there already. You can set it to overwrite if you want be removing the inner if condition and just use the first if condition with the move code.

I have not tested it be actually downloading. Only drag and drop. You may have to adjust if the folder action does not pick up on the extension change drom .download to the file actual extension

share|improve this answer

Consider using AppleScript instead of, or in combination with, Automator. Automator does not easily fit into workflows that require conditional branches.

Conditional branches are steps within the workflow that perform an action depending on some state or situation. In this case, if the video file is present in the destination folder.

AppleScript can handle this type of task; as could a perl script or other scripting language.

See Can Automator branch based on the value of a variable or the result of a step? for a script based approach combined with Automator.

Scripted Approach

For tasks like this I prefer scripting languages like perl. Below is a script that should get you started - or that others can build on. It is untested, so treat with care:

#!/usr/bin/env perl

use strict;
use warnings;

use File::Basename; # for fileparse

# WARNING: lack of error checking

# Use: ./move_srt.pl <path to source folder> <path to destination folder>

my $source_path = shift;
my $destination_path = shift;

# Get the video file names - without their 3 or 4 letter suffixes
my @destination_video_files = glob($source_path.'/*');
my %named_video_files = map { $_ => fileparse($_,qr/\..{3,4}/); } @destination_video_files;

# Get a list of srt files
my @source_srt_files = glob($source_path.'/*\.srt');

foreach my $source_srt_file (@source_srt_files) {
    print "[Encountered] $source_srt_file\n";

    # Strip suffix and check if video exists with same name
    my $named_srt_file = fileparse($source_srt_file,qr/\.srt/);
    if (exists($named_video_files{$named_srt_file})) {

        # Move the matching srt File
        system('/bin/mv '.$source_srt_file.' '.$destination_path);

        print "[Matched] $source_srt_file\n";
    } else {
        print "[Unmatched] $source_srt_file\n";
    }
}
share|improve this answer

You could also use a shell script like this:

shopt -s globstar extglob nullglob
for f; do
  [[ $f != *.@(srt|ass|ssa) ]] && continue
  base=${f##*/}
  target=$(printf %s\\n ~/Movies/**/"${base%???}"* | head -n1)
  [[ $target ]] && mv "$f" "${target%.*}.${base: -3}"
done
exit 0

You need Bash 4 for globstar, which makes ** match multiple levels of directories. You can install Bash 4 and make it your default login shell by running brew install bash;echo /usr/local/bin/bash|sudo tee -a /etc/shells;chsh -s /usr/local/bin/bash.

nullglob makes patterns with no matches expand to an empty string. for f; do is equivalent to for f in "$@"; do. When extglob is enabled, @(srt|ass|ssa) matches exactly one out of srt, ass, and ssa. Bash doesn't perform word splitting or filename expansion inside [[, so $f doesn't have to be quoted. printf %s\\n prints each argument on a separate line. ${f##*/} removes the longest */ pattern from the start, ${base%???} removes the last three characters, ${target%.*} removes the shortest .* pattern from the end, and ${base: -3} expands to the last three characters. [[ $target ]] is equivalent to [[ -n $target ]], or it tests if $target is set and not empty. exit 0 makes Automator not display an error dialog if the last test exits with 1.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.