rename n-th character -HowTo?

I’m looking for leads to do some file renaming.
Names are like this:

I need to rename to:

  • stripping Screenshot_ is easy with Hazel

But how do I replace the 11th character ‘-’ with ‘_’ without mistakingly renaming any other hyphen?


Is this a Hazel question or are you trying to do something in DEVONthink?

Why not just get a copy of A Better Finder Rename (or Name Mangler) which are built to do just this sort of thing. Export your files from DEVONthink, use one of those apps to rename them as a batch, then reimport them.

There’s not much value in learning to write your own software to do something that is already commercially available.

Both. Whichever one does it the easiest.
I just recently started to dig into Hazel a bit deeper.

I agree with these comments – scripted solutions (building your own tools) are time-consuming – much better to use something ready made and and better polished.

Just to illustrate that point (not planning to explain or support this code), you would end up having to write and integrate something like this in Sierra (ES6) JavaScript for automation:

(() => {
    'use strict';

    // splitAt :: Int -> [a] -> ([a],[a])
    const splitAt = (n, xs) => [xs.slice(0, n), xs.slice(n)];

    // intercalate :: String -> [a] -> String
    const intercalate = (s, xs) => xs.join(s);

    return intercalate('_',
        .map(x => x.replace(/\-/g, ''))

and in AppleScript, you can get into notorious tangles with the need to swap and cache “text item delimiters” all the time. Something like the JS above could be written fairly briefly as:

on run
    script withoutHyphen
        on lambda(x)
            replace("-", "", x)
        end lambda
    end script
    return intercalate("_", ¬
        map(withoutHyphen, ¬
            splitAt(11, "2016-08-26-19-28-39.jpg")))
end run

but only if you have imported (and made sense of) a whole lot of stuff like this:


-- intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
    set {dlm, my text item delimiters} to {my text item delimiters, strText}
    set strJoined to lstText as text
    set my text item delimiters to dlm
    return strJoined
end intercalate

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to lambda(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map

-- Lift 2nd class handler function into 1st class script wrapper 
-- mReturn :: Handler -> Script
on mReturn(f)
    if class of f is script then
            property lambda : f
        end script
    end if
end mReturn

-- replace :: Text -> Text -> Text -> Text
on replace(strNeedle, strNew, strHayStack)
    set {dlm, my text item delimiters} to {my text item delimiters, strNeedle}
    set xs to text items of strHayStack
    set my text item delimiters to strNew
    set strReplaced to xs as text
    set my text item delimiters to dlm
    return strReplaced
end replace

-- splitAt :: Int -> [a] -> ([a],[a])
on splitAt(n, xs)
    if n > 0 and n < length of xs then
        if class of xs is text then
            {items 1 thru n of xs as text, items (n + 1) thru -1 of xs as text}
            {items 1 thru n of xs, items (n + 1) thru -1 of xs}
        end if
        if n < 1 then
            {{}, xs}
            {xs, {}}
        end if
    end if
end splitAt

-- splitOn :: Text -> Text -> [Text]
on splitOn(strDelim, strMain)
    set {dlm, my text item delimiters} to {my text item delimiters, strDelim}
    set xs to text items of strMain
    set my text item delimiters to dlm
    return xs
end splitOn

Actually I’m a bit fed up with thinking wallet when I search for a solution.
Mind you, not that I am against purchasing one of those you mentioned.
However, I’m in the habit of trying to do ‘prepared’ purchases instead of on the spot, this will (probably) do the trick.

Are you 100% sure either of the 2 you mention will do the trick?
Which one do you use / prefer?

WoodChopper - HaHa - you should have chosen CodeChopper if you ask me!
Thanks for dropping in!

I agree with you all, thanks for your suggestions.
I was living with the idea that Hazel could do this…

I’m looking at ABFR now -
I do hope the learning curve will not be too steep…
(Do they have an active supporting forum??? Can’t be any better than Devonthink!! :mrgreen: