Rename then copy MOVE a file fails because windows still thinks file has old filename

I still recommend you at least try the first two bullet points :slight_smile:

Yes I did wonder about them. Sometimes these command strings have worked then stopped.
I have seen them work with 2 backslashes before on FAYT and now they do not for example.
the first 2 bullet points are

  • Remove the space - I have tried that and it breaks.
  • Add a p toe escregex for give escregexp

Once again..... thank you

The three points were designed as a complete meal, not a bag of Belgian chocolates to pick whatever you fancy :face_with_raised_eyebrow:

1 Like

Opus Wizards
The penny has dropped ... all 3 items above are required
For any otehr users out there reading this the tricky thing to understand is that I might get the syntax nearly correct (but still incorrect) and it works when tested. E.g. item 1 below. Only one backslash but my test was good.
Only when I make a change (Remove extraneous space item 2 below) does the backslash issue show up as a fault.
Fixing the backslash gives us item 3 .... all good.

Sorry this one will just not die.
Test 14 below is for reference. It works and is the result of kind help from above.
Test 15 is broken. It is my attempt to remove the Select Destination Folder dialog which is part of the working Test 14.
What have I done wrong?

Looks like the mistake from six days ago. Rename needs the long version of an alias: {alias|work} instead of /work.

Ah!!
Sorry @Ixp I don't mean for you to be telling me stuff twice.
Below is repeat of test15 above fixed so it is working.

One reason I am slow on the uptake is that I am not understanding what is represented between the curly brackets. So below is an bit of a study and analysis. Any comments/corrections appreciated:

In the case of Test15b above
{alias|Work|regexp}
These seem to be Codes for passing filenames which are a form of External control codes. These, despite the reference to external programs, "may also be used with the internal commands":

In particular, {alias|Work|regexp} are modifiers.

{alias}
{alias} is in fact a Code for passing paths (Makes sense. Here is the explanation from the manual below)
Although it does not specifically say so, it seems that you need 2 entries of the form
{AAA|BBB}
where
AAA = Static keyword "alias"; and
BBB = the actual alias that you want to reference. In my case above the alias is /Work. Note I do not have the forward slash in as part of the modifier. Just the alias work

{work}
This is the actual alias to be referenced as per my explanation above.

{escregexp}
If excluded then this breaks test15b above.
The regex capture group \1 is interpreted as a literal digit 1 unless when this modifier is missing.
It is interesting to me that the modifier is INSIDE the curly brackets and the capture group is OUTSIDE.
My understanding was that the modifier only affects what is inside the curly brackets. Apparently not.
Also if missing then test 14 above does NOT break. Don't know why but I have learned the hard way to stick to instructions from @Ixp :slight_smile:

{escbackslash}
Manual notes below.
This is in fact not part of my working commands but was suggested by @Ixp at one point above.
Note I am in fact using 4 x Backslashes //// in the script string.
Separate analysis to follow

Four Backslashes == 4 x / == ////
Consider my working "ASK" internal command string.
The string a written within the script (I call this the "in script" form) has 4 backslashes see Note 2 below.
Why?
Once the script has run it passes the command to opus in the form shown in Note 1 below. ("out of script" form)
Reg regex capture group syntax calls for the form \n where n is the capture group number.
In my command I have only one capture group so the regex syntax is \1
The TO="...." component of the command has inverted commas (double quotes) around it.
Because of this an additional backslash is required as an escape character to present the second backslash as a literal. Hence double backslash in the "out of script" command form (Note1)
The In script string has additional inverted commas (single quotes). Because of this, for the same reason as above, an additional backslash is needed for each existing backslash.
Hence 4 backslashes in all.

By writing out the above I have improved my understanding of the tools I am using. Hope I can be more self sufficient going forward!!!! Thank you! Gracias! Merci beau coupe! Etc. Etc.!!!!!

A few comments :slight_smile:

:one:

escbackslash vs. escregexp: escbackslash is probably only useful outside renames (though it often will work). For any regex rename, use escregexp.

:two:

the modifier only affects what is inside the curly brackets. Apparently not

Rule: The modifier only affects what is inside the curly brackets!

Look further down for an exception :hushed:

:three:

single vs. double quotes: a pure JScript thing. I like to use single quotes for JScript and reserve the double quotes for Opus commands. Going "all double quotes" is possible, but then you would need even more \ :slight_smile:

:four:

The string a written within the script (I call this the "in script" form) has 4 backslashes see Note 2 below. Why?

The script variant has \\\\ because the normal command has \\. Why? Again, a pure JScript thing: "backslashes need to be escaped (with backslashes)". Period :slight_smile:

So the more interesting question is: Why does the normal variant use \\?

Well, I thought I had a good explanation. Turned out I didn't. At least not in the way I originally envisioned. I now think it's a bug. I've written a separate report.

:five:

General advice: There is nothing wrong with using codes in Rename statements, especially if you want to be able to later/again/also use the statements in normal (non-script) buttons. But if you go all-in with scripting, use the item properties and the JScript regex support. It'll make your code a lot easier to understand/debug/maintain :+1:

2 Likes

I... errrm need more help.

:zero: Thanks
(BTW Thanks @lxp now I can do fancy numbering :one: /:two: /:three: etc. Nice. I love fancy ■■■■ like that :slight_smile: )

:one: Existing working Internal Command (IC)
With thanks to @lxp and others I have the following in the back which works:

rename PATTERN=(.*) TO="{alias|' + Destination_Alias + '|escregexp}\\\\1' + Str_Suffix + '" REGEXP IGNOREEXT

This IC will act on the currently selected files as follows:
:gear: Rename the files by adding the suffix defined in the variable Str_Suffix
:gear: Move the files to the folder defined by the alias contained in the variable Destination_Alias
This is cool.

:two: Objective
To add a subfolder in the Destination_Alias and move the renamed files to that subfolder.

:three: Approach
I find it difficult to present clearly here what changes I have tried and the results I have got.
So rather then causing confusion I thought I would present my analyis of the working command above with a view to understanding it better.
Then I might be better equipped to tackle these things on my own.
I am particularly interested in 2 occurrences of backslashes as follows

:four: Inscript vs OutScript
InScript - This is the IC string that is assembled within the Javascript code.
OutScript - When the JS runs it presents the IC string to Opus to run. The form that is presented changes somewhat from the original InScript form. The OutScript form has to work from a button. It can be tested by executing it via the FAYT prompt.

:five: Regex Capture Group Backslashes
Q1 Is this analysis correct?
This is highlighted in light turqois and number 1 in the screenshot.
InScript - \\\\1 - Four required in order to present 2 backslashes in the OutScript string
OutScript - \\1 - First \ acts as an escape character to signal that the second \ is a literal
Filename - \1 - This represents the single Regex Capture group in our case the entire filename stem.

:six: Folder Delineator Backslash
Q2 Is this analysis correct?
This is highlighted in orange and number 2 in the screenshot.
InScript - - This backslash is not explicitly defined here. I assume that it is provided as part of the "path of the folder alias". (Quoted from the definition of the {alias} external control code. There is a screenshot of this defintion in the post above.)
OutScript - - Not present here for the same reason as above.
Filename - - This is inferred to be present as the IC command works as intended. the fully qualified name (i.e. complete with path) would necessarily have the aforementioned \ in the right place.

:seven: Add a subfolder to the destination
Q3 What would the correct IC form be to do this?
As mentioned above I am not presenting my attempt here as I think it will confuse things.
I have made several attempts actually.
And the results I have got have gien me reason to be interested in the backslash situation above.

With thanks as always

Here's a little something to play with. Needed more backslashes than I anticipated, but apparently also the Rename statement wants more than its fair share of \. Have fun!

function OnClick(clickData) {
    var cmd = clickData.func.command;
    cmd.deselect = false;

    cmd.RunCommand('Set UTILITY=otherlog');

    DOpus.ClearOutput();

    var Destination_Alias = 'work';
    var newFolder = 'I am new here';
    var Str_Suffix = ' suffix';

    var cmdLine = 'Rename PATTERN=(.*) TO="{alias|' + Destination_Alias + '|escregexp|noterm}' + '\\' + newFolder + '\\' + '\\\\1' + Str_Suffix + '"' + ' REGEXP IGNOREEXT';

    DOpus.Output(cmdLine);
    // cmd.RunCommand('dopusrt /argsmsgbox ' + cmdLine);
    cmd.RunCommand(cmdLine);
}
Button as XML
<?xml version="1.0"?>
<button backcol="none" display="label" hotkey_label="yes" label_pos="right" textcol="none">
	<label>45763 JS</label>
	<tip>rename-then-copy-move-a-file-fails-because-windows-still-thinks-file-has-old-filename</tip>
	<icon1>#script</icon1>
	<function type="script">
		<instruction>@script JScript</instruction>
		<instruction>function OnClick(clickData) {</instruction>
		<instruction>    var cmd = clickData.func.command;</instruction>
		<instruction>    cmd.deselect = false;</instruction>
		<instruction />
		<instruction>    cmd.RunCommand(&apos;Set UTILITY=otherlog&apos;);</instruction>
		<instruction />
		<instruction>    DOpus.ClearOutput();</instruction>
		<instruction />
		<instruction>    var Destination_Alias = &apos;work&apos;;</instruction>
		<instruction>    var newFolder = &apos;I am new here&apos;;</instruction>
		<instruction>    var Str_Suffix = &apos; suffix&apos;;</instruction>
		<instruction />
		<instruction>    var cmdLine = &apos;Rename PATTERN=(.*) TO=&quot;{alias|&apos; + Destination_Alias + &apos;|escregexp|noterm}&apos; + &apos;\\&apos; + newFolder + &apos;\\&apos; + &apos;\\\\1&apos; + Str_Suffix + &apos;&quot;&apos; + &apos; REGEXP IGNOREEXT&apos;;</instruction>
		<instruction />
		<instruction>    DOpus.Output(cmdLine);</instruction>
		<instruction>    // cmd.RunCommand(&apos;dopusrt /argsmsgbox &apos; + cmdLine);</instruction>
		<instruction>    cmd.RunCommand(cmdLine);</instruction>
		<instruction>}</instruction>
	</function>
</button>
1 Like

It works! But you knew that :slight_smile: Thanks...

:one: Regret one more - Call this "Folder-Ask-XX" or "FAxx"
It is with great regret that I approach once more.
The last piece in my scripting jigsaw is to alter the IC command string that @Ixp generated above to achieve the following.
I was determined to manage this one myself but alas...

:two: Variables

var Destination_Alias = 'work';
var newFolder = 'I am new here';
var Str_Suffix = ' suffix';

:three: Internal Command Actions
With the currently selected files

  1. Throw up the Opus {dlgfolder|Your choice!| + Destination_Alias}
  2. Create a subfolder in the selected (destination location defined by variable = newFolder)
  3. Add the suffix to the selected files as defined by variable Str_Suffix = ' suffix';
  4. Move the selected (and prefixed) files to the newly created subfolder

The above amount to exactly what @Ixp nutted out for me in the "have fun" script above with the single exception that the {dlgfolder|Your choice!| + Destination_Alias} is thrown up. No other difference.

:four: Target Internal Command
I believe this is the IC we want to generate from JScript.
The variables are assigned as follows:
Destination_Alias = '/work';
var newFolder = 'SubFolder';
var Str_Suffix = ' 4444'; (Noted first character is a space)

Rename PATTERN=(.*) TO="{dlgfolder|Your choice!|/Work|escregexp|noterm}\SubFolder\\\1 4444" REGEXP IGNOREEXT

:five: My Results
For what they are worth, a selection of my test results which seem to me informative are below.
Once again I have issues with backslashes having, what seems to me, random effects...

Let's end the suffering and do a normal rename, shall we?

function OnClick(clickData) {
    var cmd = clickData.func.command;
    cmd.deselect = false;

    cmd.RunCommand('Set UTILITY=otherlog');

    DOpus.ClearOutput();

    var Destination_Alias = 'work';
    var newFolder = 'I am new here';
    var Str_Suffix = ' suffix';

    var cmdLine = 'Rename PATTERN=* TO="{dlgfolder|Your choice!|/' + Destination_Alias + '|noterm}' + '\\' + newFolder + '\\' + '*' + Str_Suffix + '"' + ' IGNOREEXT';

    DOpus.Output(cmdLine);
    // cmd.RunCommand('dopusrt /argsmsgbox ' + cmdLine);
    cmd.RunCommand(cmdLine);
}
Button as XML
<?xml version="1.0"?>
<button backcol="none" display="both" hotkey_label="yes" label_pos="right" textcol="none">
	<label>45763b JS</label>
	<tip>rename-then-copy-move-a-file-fails-because-windows-still-thinks-file-has-old-filename</tip>
	<icon1>#script</icon1>
	<function type="script">
		<instruction>@script JScript</instruction>
		<instruction>function OnClick(clickData) {</instruction>
		<instruction>    var cmd = clickData.func.command;</instruction>
		<instruction>    cmd.deselect = false;</instruction>
		<instruction />
		<instruction>    cmd.RunCommand(&apos;Set UTILITY=otherlog&apos;);</instruction>
		<instruction />
		<instruction>    DOpus.ClearOutput();</instruction>
		<instruction />
		<instruction>    var Destination_Alias = &apos;work&apos;;</instruction>
		<instruction>    var newFolder = &apos;I am new here&apos;;</instruction>
		<instruction>    var Str_Suffix = &apos; suffix&apos;;</instruction>
		<instruction />
		<instruction>    var cmdLine = &apos;Rename PATTERN=* TO=&quot;{dlgfolder|Your choice!|/&apos; + Destination_Alias + &apos;|noterm}&apos; + &apos;\\&apos; + newFolder + &apos;\\&apos; + &apos;*&apos; + Str_Suffix + &apos;&quot;&apos; + &apos; IGNOREEXT&apos;;</instruction>
		<instruction />
		<instruction>    DOpus.Output(cmdLine);</instruction>
		<instruction>    // cmd.RunCommand(&apos;dopusrt /argsmsgbox &apos; + cmdLine);</instruction>
		<instruction>    cmd.RunCommand(cmdLine);</instruction>
		<instruction>}</instruction>
	</function>
</button>
1 Like

@Ixp @Leo and all

:one: Appreciation
First of all I really want to say the help you give is above and beyond.
You really need to have some sort of premium support option for this kind of help.
I would happily sign up.

:two: Folder-Ask-XX or FAXX
I have edited my last request above for which @Ixp has supplied a script (which works of course) to give it a name - Folder-Ask-XX or FAXX. It is the 4th and last IC string I need for my script.

:three: Result
@Ixp's script works. Of course it would. I see you dropped the REGEX as it is not required.
When I incorporate it into my script.....it appears to fail!
This is both

  • Discouraging in that this thing will not die; but on the other hand
  • Encouraging in the sense that I have not obviously been doing anything silly when I tried myself; and I have, believe it or not made a real effort before I appeal for help here. I always do.

:four: Next step - Me troubleshoot my Script
I want to validate what I have seen and make sure I am not making any errors in testing.
Then I will troubleshoot probably by stripping code out my script & progressively testing along the way until either

  • It starts working; OR
  • I strip out enough to make it identical to the working control i.e. Ixp's solution provided above

Hopefully I will solve myself or failing that be able to present any issue in the clearest simplest way possible for anyone to see.

:five: DOpus current version
During most of this blog I have in fact been running Opus 12.21. On 22nd (Friday) I upgraded to the current version as shown below.
There was no change to any of the symptoms/results I was getting at the time.
Directory Opus Pro 12.33 Build 8659 x64
OS 10.0 (B:19045 P:2 T:1) SP 0.0

:six: Windows Update
I see I have a Windows Update ready. I will be installing that and reloading at regular intervals when testing.

Thank you and happy Sunday!

Posting the entire concoction might be the easiest :slight_smile:

been running Opus 12.21

Really? This release is over three years old.

I am starting a new job tomorrow so unfortunately I will not be able to spend much time on this I think.
Pity as I sense momentum and interest is high. Very helpful to me.
I hope I have checked this ok but I have cut down my script and the delta can be seen in the OutofScript presenation in the DOpus.Output of each script. See screenshot below. The InScript string should be identical in both Control(@Ixp) and Broken(@Shaun) scripts. i.e. that which you supplied above (unless I have made an error)

021_051.dcf (15.7 KB)

// Broeken Script ver 021_051 
//
function OnClick(clickData)
{
    DOpus.ClearOutput;
    DOpus.Output("001000 Start 021_051");
    var Str_Suffix = " 4444";
    var FeatureMask = 0xD;
    var cmd = clickData.func.command
	cmd.deselect = false;
        Destination_Alias = "Work"
        DOpus.Output("          040  Str_Suffix                :::"+ Str_Suffix + ":::");
        DOpus.Output("          270  Destination_Alias         :::"+ Destination_Alias + ":::");
        DOpus.Output("          310  FeatureMask               :::"+ ZeroPad((FeatureMask).toString(2),4) + ":::");
            Str_Folder = "NewSubF"
        DOpus.Output("          320  Str_Folder                :::" + Str_Folder + ":::");
        //
        FeatureMask = ZeroPad(FeatureMask.toString(2),4)
        DOpus.Output("   004000-100-000  FeatureMask                   =  " + FeatureMask);
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
        Str_Folder = ""
		Str_Command_FAxx_Folder__Ask_13_Ixp   = 'Rename PATTERN=* TO="{dlgfolder|Your choice!|/' + Destination_Alias + '|noterm}' + '\\' + Str_Folder + '\\' + '*' + Str_Suffix + '"' + ' IGNOREEXT';
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
        if (FeatureMask.charAt(0) === '1')                           // <-----------------------------------------------------------------------------------------------------
    	{
            DOpus.Output("Hit on Case 1000 FOLDER");
            //
            DOpus.Output("          ...AND 0100 ASK");
            DOpus.Output("          280-100  Case FeatureMask        -A-- =  " + ZeroPad((FeatureMask&0x4).toString(2),4));
            Str_Command_EXEC = Str_Command_FAxx_Folder__Ask_13_Ixp
            DOpus.Output("          280-110  Str_Command_EXEC = Str_Command_FAxx_Folder__Ask_13_Ixp   :" + Str_Command_FAxx_Folder__Ask_13_Ixp);
        }                                                              // <-----------------------------------------------------------------------------------------------------
        DOpus.Output("");
        DOpus.Output("004000-300-100  Str_Command_EXEC   =                                        :" + Str_Command_EXEC);
        CmdResult = cmd.RunCommand(Str_Command_EXEC);
    DOpus.Output("005000 Process Dialog box RETURN END");
    DOpus.Output("");
}

function ZeroPad(s,c)
{
	s = s + "";
	while(s.length < c)
	{
		s = "0" + s;
	}
	return s;
}

Line 15 is

Str_Folder = "NewSubF"

but line 21 is

Str_Folder = ""

So it's no big surprise it's missing in the final command statement.

Or did I misunderstand the problem?

The script is butchered, that's the only logical explanation I can find for what I see.

Oh dear that is embarrassing and also great news.
I would have found it eventaully haha!
I will have a proper look asap but I think you have found my problem. Again.
I wanted to fix this last item before I start work at new job and it is literally 0623h here
Thanks so much!!!!!

So...
With kind help I have 4 rename commands that are components of my script.
One of them, grandly named Str_Command_00xx_NoAsk has an Inscript string as follows:
'rename PATTERN=(.*) TO="{alias|' + Destination_Alias + '|escregexp}\\\\1' + Str_Suffix + '" REGEXP IGNOREEXT'

In some cases Str_Suffix is empty. In such cases the OutScript resolves to the following:
rename PATTERN=(.*) TO="{alias|al20|escregexp}\\1" REGEXP IGNOREEXT
Where
al20 = The alias being referenced

It seems that when the alias resolves to a path that has itself no spaces then it works.
But if there is a space then the filename is changed to "1.png".
Working and control results below are generated from FAYT with the OutScript strings shown.
No script run for these tests.

Any ideas how I might address? With thanks...