Renaming Files With Spaces in the Filename

I'm trying to use the "Move or Rename a File" action to rename a file, and it seems to only work if the filenames contain no spaces. What is the solution for this?

Details:

The first value interpolates to:

/Users/todd/file 1.wav

And the second to:

/Users/todd/file 2.wav

If I remove the spaces from the filenames, it works just fine. And oddly, directories can contain spaces without causing problems. I'm trying to figure out how the 'mv' command is being used behind the scenes here, but I just don't get it. I also tried adding single quotes around my variable interpolations but it just gets more confused. What am I missing here?

For completeness, here is the log entry:

2021-11-21 13:46:45 Action 1039 failed: Move file /Users/todd/file 1.wav

failed with Error Domain=NSCocoaErrorDomain Code=4 "“file 1.wav

” couldn’t be moved to “Sessions” because either the former doesn’t exist, or the folder containing the latter doesn’t exist." UserInfo={NSSourceFilePathErrorKey=/Users/todd/file 1.wav

, NSUserStringVariant=(

Move

), NSDestinationFilePath=/Users/todd/file 2.wav, NSFilePath=/Users/todd/file 1.wav

, NSUnderlyingError=0x600000e4eb50 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}

Hey Todd,

Welcome to the forum!  :sunglasses:

Nyet. Keyboard Maestro manages spaces just fine, so there is likely some small problem with your macro.


Moderator hat on...

When posting macros to the Keyboard Maestro forum please use these guidelines:

  1. Always post a Macro File.
  2. Always post an image.
  • Providing a test-case macro means people won't have to reinvent the wheel to help you, and that significantly improves the likelihood that someone will help you.

  • Verbal descriptions frequently leave out details crucial to solving the problem, while a properly constructed test-case macro will intrinsically contain them.

    • A test-case should be the minimal possible macro that demonstrates the problem.
  • Folks generally won't download something they haven't eyeballed first, so an image of the macro is vital.


If you haven't seen these they're worth a moment of your time:

How to Post Your Macro to the Forum

Tip: How Do I Get The Best Answer in the Shortest Time?

Moderator hat off...


Rule-of-the-thumb – never compose complex commands or paths in the action that uses them – at least while prototyping. It's too easy to introduce an error that's very difficult to see.

Use variables and display text actions to let you properly visualize compositions before trying to use them.

See the appended test macro for an example of same.

Note the orange action where a file name with spaces resides.

-Chris


Move a File with Spaces in the File Name v1.00.kmmacros (8.8 KB)
Keyboard Maestro Export

I think single quotes inhibit the expansion of "~" and "$HOME" etc.

It may be worth flanking the variable tokens with double quotes instead.

Since you haven't shown your work who can say?

But @ComplexPoint may be on to something.

Ah, an active forum, with guidelines no less! How refreshing. :slight_smile: I will upload the macro and image below.

Rule-of-the-thumb – never compose complex commands or paths in the action that uses them – at least while prototyping. It's too easy to introduce an error that's very difficult to see.

Use variables and display text actions to let you properly visualize compositions before trying to use them.

Good advice. Fwiw, I did that prior to posting – I defined the paths in variables, then used an 'Alert' action to view them on screen, and as a sanity-check I even dumped them to text files and copy-and-pasted the text into my own 'mv' command on the command line (with single quotes around the paths to deal w/the spaces) and that test was successful, so I knew my variable interpolation logic was good, and eventually moved the complex paths directly into the command.

I looked at the posted macro, though I'm still not seeing what I'm doing wrong. I notice the end of that macro is a copy command (vs move/rename) – I wonder if those commands operate differently on the backend.

Rename Project Macro.kmmacros (4.5 KB)

Nyet.

You're making all the right moves.

But Keyboard Maestro does not use mv behind the scenes; it uses the macOS File Manager.

I'll look at your macro in a minute.

Hey @ToddG2,

You're missing values for the variables:

NewProjectName
ProjectName

In your macro.

Please revise and repost.

-Chris

Gotcha, I didn't realize anyone was going to run the macro, but that's great - I re-cloned it and slimmed it down a bit, with all the required variables defined. I also tested extensively to make sure this replicates the issue and it does. Here is the new version:

Rename Project Copy.kmmacros (6.9 KB)

I also found a new clue in the logs that may indicate what's going on here. What follows is the Engine.log block that results from running the attached macro. Look closely at the log entries that list the old file path that ends with Old Project Name.jpg:

2021-11-22 16:58:20 Execute macro “Rename Project Copy” from trigger Editor
2021-11-22 16:58:27 Log: Old: /Users/todd/Old Project Name/Sessions/Old Project Name.jpg

2021-11-22 16:58:27 Log: New: /Users/todd/Old Project Name/Sessions/New Project Name.jpg
2021-11-22 16:58:27 Action 2661 failed: Move file /Users/todd/Old Project Name/Sessions/Old Project Name.jpg
failed with Error Domain=NSCocoaErrorDomain Code=4 "“Old Project Name.jpg
” couldn’t be moved to “Sessions” because either the former doesn’t exist, or the folder containing the latter doesn’t exist." UserInfo={NSSourceFilePathErrorKey=/Users/todd/Old Project Name/Sessions/Old Project Name.jpg
, NSUserStringVariant=(
Move
), NSDestinationFilePath=/Users/todd/Old Project Name/Sessions/New Project Name.jpg, NSFilePath=/Users/todd/Old Project Name/Sessions/Old Project Name.jpg
, NSUnderlyingError=0x60000221a970 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
2021-11-22 16:58:27 Move file /Users/todd/Old Project Name/Sessions/Old Project Name.jpg
failed with Error Domain=NSCocoaErrorDomain Code=4 "“Old Project Name.jpg
” couldn’t be moved to “Sessions” because either the former doesn’t exist, or the folder containing the latter doesn’t exist." UserInfo={NSSourceFilePathErrorKey=/Users/todd/Old Project Name/Sessions/Old Project Name.jpg
, NSUserStringVariant=(
Move
), NSDestinationFilePath=/Users/todd/Old Project Name/Sessions/New Project Name.jpg, NSFilePath=/Users/todd/Old Project Name/Sessions/Old Project Name.jpg
, NSUnderlyingError=0x60000221a970 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}} in macro “Rename Project Copy” (while executing Rename the session file).

You'll notice every instance in the log that prints the old filepath has an extra linebreak at the end, right after .jpg. That shouldn't be there. It's most obvious if you look at the part of the log where it double-quotes the old filename. Between .jpg and the closing quote, there is an extra linebreak.

That extra line break led me to believe that the action Rename everything in Sessions is appending a linebreak to the end of the SelectedPath. So I did some additional experiments with the individual components of that path after they are parsed into new variables by the action Split up SelectedPath into its components.

I did a number of experiments where I pieced together the components of the path, e.g.:

%Variable%SessionsDirPath%%Variable%SessionPathBaseName%.%Variable%SessionPathExtension%

But it appears that every one of the parsed components (including the extension) also contains an extra linebreak at its end. That's what appears to be happening as far as I can tell. But it also seems like that is the sort of bug that would affect an awful lot of macros out there, so I'm curious if I'm barking up the wrong tree.

Trying to debug a macro by eye only is a recipe for wasted time.

If we're not testing we're guessing, and guessing nearly always wastes everyone's time.

:sunglasses:

1 Like

You introduced the linefeed in the Move field.

image

Place your cursor at the end and down-arrow.

I recommend that you never depend upon folder paths having a trailing slash.

Unix canon is:

/root/subfolder1/subfolder2

Personally I hate this, because it make it impossible to tell at a glance whether you're working with a directory or a file.

My compromise is to always define directory paths like this:

/root/subfolder1/subfolder2/

And then use a filter action to Standardize Path which produces:

/root/subfolder1/subfolder2

I make sure that no directory path hidden in a variable has a trailing slash, so I always know exactly what I'm dealing with when I assemble paths with substrings.

-Chris

That's fantastic, it works! Thanks so much Chris!

1 Like