0

I have a text file list of approx 120,000 filenames. Many of the files on the list are in a folder or it's subfolders, but with slight variations on the filenames.

so I want to search using the list of partial filenames and copy the matches to another folder.

Each line on the list is a name and a title separated by a bar for example:

A Name|The Title
John Smith|A Life

The files are various text formats and all have extra stuff in the filenames like:

A Name - The Title V1.4 (html).lit
John Smith - A Life: Living on the Edge [MD] (pdf).rar

I've tried the code from this thread and this thread but neither are finding any of the files. Can anyone help please.

Paul Cook
  • 27
  • 2
  • 4
  • Does each matching file *start* with the name from your list, or can the name appear *anywhere* in the matching file? Your example filename `John Smith - A Life: Living on the Edge [MD] (pdf).rar` is invalid. Please provide real examples. – Magoo Jan 31 '18 at 01:30

3 Answers3

1

This PowerShell script assumes that if both the first field "name" and the second field "title" are anywhere in the filename that it should be copied. When you are confident that the correct files will be copied, remove the -WhatIf from the Copy-Item command.

Note that this does not address the issue of multiple files with the same name.

If you wanted to require the "name" field to be at the beginning of the string, you could add it to the match expression. $_.Name -match '^'+$pair.name. If you want the matches to be case sensitive, use -cmatch.

$sourcepath = 'C:\src'
$targetpath = 'C:\other'

$searchpairs = Import-Csv -Header "name","title" -Delimiter "|" -Encoding ASCII -path .\mdb.txt

foreach ($pair in $searchpairs) {
    Get-ChildItem -Recurse -File -Path $sourcepath |
        Where-Object { ($_.Name -match $pair.name) -and ($_.Name -match $pair.title) } |
        ForEach-Object { Copy-Item $_.FullName $targetpath -WhatIf}
}
lit
  • 14,456
  • 10
  • 65
  • 119
0

Might not be the solution you are looking for, but I ditched batch scripting years ago. I use Powershell instead, and simply call the Powershell script from batch file.

Here is the code in case you are interested,

searchfiles.ps1

$searchStrings = @("city", "sniper") # Declare an array to iterate over.

foreach ($string in $searchStrings) {
    Get-ChildItem -Path D:\Movies\Movies | ? { $_ -match $string }
}

And now call the Powershell script from batch file.

searchfiles.bat

Powershell.exe -ExecutionPolicy RemoteSigned -Command "& searchfiles.ps1 -Verb RunAs"

Hope it helps!

That's not to say I don't use batch scripting at all. I will use them only for simpler operations, like calling another script, or opening a folder, etc. With Powershell, I love taking the help of the underlying .NET framework and sweet piping!

scorpion35
  • 944
  • 2
  • 12
  • 30
0

Adjust the paths and you should be good with this one:

@ECHO OFF


REM **************************************************

REM Adjust location of list
SET list=C:\adjust\path\list.txt

REM Source dir
SET source=C:\adjust\path\source

REM Target dir
SET destination=C:\adjust\path\destination

REM **************************************************



FOR /F "tokens=1,* delims=|" %%A IN (%list%) DO (
    ECHO.
    ECHO %%A - %%B
    CALL :copy "%%A - %%B"
)   

ECHO.
ECHO Done^!
PAUSE
EXIT

:copy
FOR /R "%source%" %%F IN (*) DO (
    ECHO "%%~nF" | FINDSTR /C:%1 >nul && COPY "%%~fF" "%destination%\%%~nxF" && EXIT /B
)
EXIT /B

Be aware: this requires the scheme in list.txt to be A|B and the scheme of every file to be copied *A - B* (including spaces) while * may be no or any character(s).

FatalBulletHit
  • 762
  • 6
  • 22
  • Thanks. That didn't actually work but it did show me why none of them are working for me. I have 20K folders with 500K files - it's too much for it, so it never gets past the first one on the list. I think I need to create a list of all the filenames and search that instead of the actual files? – Paul Cook Feb 01 '18 at 13:54
  • You could split up the list in multiple lists, maybe that will work (just do not start multiple batch-files at once). But in theory batch should be capable of handling 500'000 files, it will just take some time (several hours at least, `FOR` is not really fast and I don't know if CPU or drive are a factor, too). – FatalBulletHit Feb 01 '18 at 17:59
  • I ended up using the Everything search command line tool (ES.exe) [link](https://www.voidtools.com/forum/viewtopic.php?f=2&t=5762&hilit=ES+search#p16033) . It managed it but it took 7 hours. – Paul Cook Feb 03 '18 at 23:38