Page 1 of 2

Compare files names only, without extension and prefix

Posted: Mon 01 Dec, 2014 19:06
by KlepetoX
I need macro that compares files on both panels without extensions and prefix (after first space in filename) - filenames only. Example:

Code: Select all


The same (will be selected):

03 Forgotten Hopes.flac  |  06 Forgotten Hopes.mp3
1-14 Transacoustic.mp3   |  05 Transacoustic.ape
06 One Last Goodbye.mp3  |  2-05 One Last Goodbye.mp3
Will anybody help?

Compare files names only, without extension and prefix

Posted: Tue 02 Dec, 2014 00:42
by Shmuel
KlepetoX wrote: Will anybody help?
What kind of help do you need? Did you try to write this macro yourself?

Compare files names only, without extension and prefix

Posted: Tue 02 Dec, 2014 19:35
by KlepetoX
I finally did it. It may be useful for somebody. Shmuel, please see if something should be done better. I am an common user only, not programmer or macro "writer" :-)

Code: Select all

Macro {
  key="ShiftDivide";
  area="Shell Search";
  description="Select files with the same names without numeric prefix and extension";
  condition=function()
    return APanel.Visible and PPanel.Visible and not APanel.Empty and not PPanel.Empty
  end;
  action=function()
    Panel.Select(0,0) Panel.Select(1,0)    -- deselect first
    local ia,ip                            -- cycle counters for active/passive panel
    local AName,PName,ANameOnly,PNameOnly  -- file name in active/passive panel, file name in a/p panel without prefix and ext.
    local i,j                              -- cycle counters for filename scan (searching for first alpha char.)
    local s,t                              -- character from filename, if it is alpha char., do action and break cycle
    for ia=1,APanel.ItemCount do
        AName=mf.fsplit(Panel.Item(0,ia,0),0x4) -- name without extension
        for i=0,mf.len(AName) do
            s=mf.substr(AName,i,1)
            i=i+1
            if far.LIsAlpha(s) then ANameOnly=mf.substr(AName,i-1)
               for ip=1,PPanel.ItemCount do
                   PName=mf.fsplit(Panel.Item(1,ip,0),0x4)
                   for j=0,mf.len(PName) do
                       t=mf.substr(PName,j,1)
                       j=j+1
                       if far.LIsAlpha(t) then PNameOnly=mf.substr(PName,j-1) break else PNameOnly='' end
                   end
                   if ANameOnly:upper()==PNameOnly:upper() then Panel.Select(0,1,1,ia) Panel.Select(1,1,1,ip) end
               end
               break
            end
        end
    end;
  end;
}


Compare files names only, without extension and prefix

Posted: Tue 02 Dec, 2014 23:06
by Shmuel
KlepetoX wrote: I finally did it.
And I'm very glad you did it!
Here is a somewhat shorter version of your macro:

Compare files names only, without extension and prefix

Posted: Wed 03 Dec, 2014 11:27
by Shmuel
Here is a variant optimized for speed.
Tested on the System32 directory shown in both panels (2700 files and folders).
Not optimized version: 55000 msec
Optimized version: 160 msec

Compare files names only, without extension and prefix

Posted: Thu 04 Dec, 2014 19:25
by KlepetoX
Thank you, Shmuel, it works best this way

Compare files names only, without extension and prefix

Posted: Thu 11 Dec, 2014 10:26
by KlepetoX
I have edited macro trying to ignore some more charecters than prefix and extension only. I have tried mf.replace, regex.gsub and :gsub. Each of them is slow, is there another faster possibility?

Code: Select all

Macro {
  key			="ShiftDivide";
  area			="Shell Search";
  description	="Select files with the same names without numeric prefix and extension";
  condition=function()
    return APanel.Visible and PPanel.Visible and not APanel.Empty and not PPanel.Empty
  end;
  action=function()
    Panel.Select(0,0) Panel.Select(1,0)  -- deselect first
    local PTable={}
    for ip=1,PPanel.ItemCount do
      local PNameOnly=mf.fsplit(Panel.Item(1,ip,0),0x4):match("%a.*")  -- name without extension
      if PNameOnly then
        PNameOnly=mf.replace(PNameOnly,"[ _-.,!']",'')   -- fastest
--        PNameOnly=regex.gsub(PNameOnly,"[ _-.,!']",'') -- slower
--        PNameOnly:gsub("[ _-.,!']",'')                 -- slowest
        PNameOnly=PNameOnly:upper()
        PNameOnly=mf.replace(PNameOnly,'THE ','')
        PTable[ip]=PNameOnly
      end
    end
    for ia=1,APanel.ItemCount do
      local ANameOnly=mf.fsplit(Panel.Item(0,ia,0),0x4):match("%a.*")
      if ANameOnly then
        ANameOnly=mf.replace(ANameOnly,"[ _-.,!']",'')
--        ANameOnly=regex.gsub(ANameOnly,"[ _-.,!']",'')
--        ANameOnly:gsub("[ _-.,!']",'')
        ANameOnly=ANameOnly:upper()
        ANameOnly=mf.replace(ANameOnly,'THE ','')
        for ip,PNameOnly in pairs(PTable) do
          if ANameOnly==PNameOnly then
            panel.SetSelection(nil,0,ip,true)
            panel.SetSelection(nil,1,ia,true)
          end
        end
      end
    end
    panel.RedrawPanel(nil,0)
    panel.RedrawPanel(nil,1)
  end;
}


Compare files names only, without extension and prefix

Posted: Thu 11 Dec, 2014 10:32
by John Doe
KlepetoX wrote: PNameOnly=mf.replace(PNameOnly,"[ _-.,!']",'')   -- fastest
Does it really work for you?
I doubt, because it is not intended to process regexps.
KlepetoX wrote: Each of them is slow
It is unusual.
Please define your meaning for "slow".

Compare files names only, without extension and prefix

Posted: Thu 11 Dec, 2014 11:31
by KlepetoX
Does it really work for you?
I doubt, because it is not intended to process regexps.
Indeed, doesn't work at all...
Please define your meaning for "slow".
Compare 20000 files takes one minute or more (large dirs or branch plugin). In small directories it is ok.

Compare files names only, without extension and prefix

Posted: Thu 11 Dec, 2014 11:37
by John Doe
KlepetoX wrote: Compare 20000 files takes one minute or more (large dirs or branch plugin).
Is it much faster without replacement?

Compare files names only, without extension and prefix

Posted: Thu 11 Dec, 2014 11:49
by KlepetoX
You are right, not much. Speed of comparing in common directories is sufficient enough, it was only test where it seems slow, common folders haven't 20000 files :-)

Compare files names only, without extension and prefix

Posted: Thu 11 Dec, 2014 14:09
by John Doe
A bit more optimization:

Code: Select all

local function norm(name)
  name = mf.fsplit(name,0x4):match("%a.*")
  return name and name:upper() or nil
end

Macro {
  key="ShiftDivide";
  area="Shell Search";
  description="Select files with the same names without numeric prefix and extension";
  condition=function()
    return APanel.Visible and PPanel.Visible and not APanel.Empty and not PPanel.Empty
  end;
  action=function()
    Panel.Select(0,0); Panel.Select(1,0)
    local PTable={}
    for ip=1,PPanel.ItemCount do
      PTable[ip]=norm(Panel.Item(1,ip,0))
    end
    local a,p = {},{}
    for ia=1,APanel.ItemCount do
      local ANameOnly=norm(Panel.Item(0,ia,0))
      if ANameOnly then
        for ip,PNameOnly in pairs(PTable) do
          if ANameOnly==PNameOnly then
            a[#a+1],p[#p+1] = ia, ip
          end
        end
      end
    end
    panel.SetSelection(nil,0,p,true)
    panel.SetSelection(nil,1,a,true)
    panel.RedrawPanel(nil,0)
    panel.RedrawPanel(nil,1)
  end;
}

Compare files names only, without extension and prefix

Posted: Thu 11 Dec, 2014 17:35
by KlepetoX
Now it is really fast. Thanks both of you John Doe and Shmuel.

Posted: Thu 11 Dec, 2014 18:24
by John Doe
So how fast is it now? Have you done some measurements?

Compare files names only, without extension and prefix

Posted: Fri 12 Dec, 2014 09:36
by KlepetoX
Yes, I have done measurements right now. Here is result:

Left panel: 11398 files
Right panel: 11391 files

After running macro:
Left panel: 11255 files selected
Right panel: 11252 files selected

Time:
Old macro: 32 seconds
Now with John Doe's macro: 3 seconds

Great work :-)