Rename Lowercase

I would like to change to filenames of all my files to lowercase only. Is there a way to automate this? If my files were referenced and indexed I could do it from the finder using an automator service, however, all of my files are contained within DEVONthink, not referenced. I would also love to change all of the text in the comments fields to lowercase.

This does it…

-- Lowercase Name and Comment
-- Created by Jim Neumann / BLUEFROG on Mon Jul 16 2018.
-- Copyright (c) 2018 BLUEFROG / DEVONtechnologies, LLC. All rights reserved.

tell application id "DNtp"
	repeat with thisRecord in (selection as list)
		tell thisRecord
			set {name, comment} to {my lowercase(name), my lowercase(comment)}
		end tell
	end repeat
end tell

on lowercase(str)
	do shell script "echo " & (quoted form of (str as string)) & " | tr '[:upper:]' '[:lower:]'"
end lowercase

This works on a selection of files. I don’t suggest grabbing 1000+ files and running it, but test it our first, whatever you do.

Another possibility is to use the foundation framework instead of a shell script:


use framework "Foundation"

on lowercase(str)
	set str to stringWithString_(str) of NSString of current application
	return (lowercaseString() of str) as string
end lowercase

Perfect. Thank you!

If you wanted to traverse selected groups, lowercasing their contents, and those of any enclosed or descending folders too, you could write something like this in JavaScript for Automation

// MAIN ---------------------------------------------------
const main = () =>
    outlineFromTrees(x => x.root)(
        map(
            fmapPureDT(x =>
                x.type() !== 'group' ? (
                    x.name = x.name().toLowerCase(),
                    x.name()
                ) : x.name()
            ),
            Application('DevonThink Pro').selection()
        )
    );

Or, if you wanted to lowercase the names of the groups themselves as well, then more simply:

// MAIN ---------------------------------------------------
const main = () =>
    outlineFromTrees(x => x.root)(
        map(
            fmapPureDT(x =>
                (
                    x.name = x.name().toLowerCase(),
                    x.name()
                )
            ),
            Application('DevonThink Pro').selection()
        )
    );

Full code, for the first case:

(() => {
    'use strict';

    // MAIN ---------------------------------------------------
    const main = () =>
        outlineFromTrees(x => x.root)(
            map(
                fmapPureDT(x =>
                    x.type() !== 'group' ? (
                        x.name = x.name().toLowerCase(),
                        x.name()
                    ) : x.name()
                ),
                Application('DevonThink Pro').selection()
            )
        );

    // GENERIC FUNCTIONS --------------------------------------

    // https://github.com/RobTrew/prelude-jxa

    // Node :: a -> [Tree a] -> Tree a
    const Node = (v, xs) => ({
        type: 'Node',
        root: v,
        nest: xs || []
    });

    // map :: (a -> b) -> [a] -> [b]
    const map = (f, xs) => xs.map(f);

    // showJSON :: a -> String
    const showJSON = x => JSON.stringify(x, null, 2);

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // TAB-INDENTED REPORT

    // tabIndentFromTrees :: (Tree -> String) ->
    //      [Tree] -> String
    const outlineFromTrees = fnText => trees => {
        const go = indent => tree =>
            indent + fnText(tree) +
            (tree.nest.length > 0 ? (
                '\n' + tree.nest
                .map(go('    ' + indent))
                .join('\n')
            ) : '');
        return trees.map(go('')).join('\n');
    };

    // DEVONTHINK ----------------------------------------------

    // fmapPureDT :: (DTItem -> a) -> DTItem  -> Tree a
    const fmapPureDT = f => item => {
        const go = x => Node(
            f(x),
            x.children()
            .map(go)
        );
        return go(item);
    };

    // MAIN ---
    return main();
})();