Это кажется легкой задачей, но я не могу решить ее.

У меня есть файл LIST.TXT со следующим:

123456
555789
8888988898
12125

У меня есть большой объем файлов с этими номерами в начале их имен файлов:

123456_wedding1.jpg
123456_wedding2.doc
123456_wedding3.xls
555789_henrysales_horse.jpg
555789_goodtimes.mov
8888988898_33.avi
12125_some long description here.asx
12125_shor desc.asx
12125_shor desc2.xlsx

Я объявляю об отказе: theList, the Source & theDestination и просто хочу скопировать файлы в папку Destination (мне даже не нужны подпапки).

Ниже приведен код, который я пытался адаптировать от других добрых людей:

REM @ECHO OFF

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

REM Adjust location of list
SET "theList=C:\2. List\List.txt"

REM Source dir
SET "theSource=C:\2. Files\"

REM Target dir
SET "theDestination=C:\2. Found\"

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

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

ECHO.
ECHO Done^!
PAUSE
EXIT

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

pause 
EXIT /B

Тем не менее, я все еще получаю эту ошибку:

Система не может найти файл C:\2 ..

Похоже, что-то связано с пробелами в файлах или папках, но я не могу это исправить.

Ваша помощь будет высоко ценится

2 ответа2

1

Будет ли PowerShell вариант для этого? Это кажется лучшим инструментом для работы и, безусловно, сделает его проще. Например, кости решения могут быть:

$theList        = "C:\2. List\List.txt"
$theSource      = "C:\2. Files\"
$theDestination = "C:\2. Found\"
$toCheck        = gc $theList  

Get-ChildItem $theSource | Foreach-Object{        
    if($toCheck -match $_.BaseName)
    {
       write-host "matches in list file $($theList):" $_.FullName
       copy-item $_.FullName -destination $theDestination
    } 
}

Это просто скопирует файл. Если вы хотите переместить его, подумайте об использовании Move-Item.

Если вы действительно хотите, чтобы подстроки базового имени файла совпадали с записями в файле списка, более детально, чтобы он был читабельным, а вы могли изменить или расширить, может помочь следующее:

$theList        = "C:\2. List\List.txt"
$theSource      = "C:\2. Files\"
$theDestination = "C:\2. Found\"
$toCheck        = gc $theList  

function inArrayasSub([string]$stringToCheck)
{
    write-host "`tchecking: '$($stringToCheck)' exists (substring) in file " $theList 

    foreach ($entry in $toCheck)
    {
       if ($stringToCheck -match $entry)
       {
           write-host "`tExists based on entry: $entry"
           return $true 
       }
    }
    return $false
}

Get-ChildItem $theSource | Foreach-Object{

    write-host "Testing file basename: "$_.BaseName

    if (inArrayasSub $_.BaseName)    
    {
       write-host $_.BaseName "matches in list file $($theList):" $_.FullName
       copy-item $_.FullName -destination $theDestination
    } 
    write-host "======================"
}
1

Пакетный файл который:

  • разбивает все файлы из источника на подчеркивание
  • использует findstr /G: для сравнения разбитого числа со списком
  • если номер присутствует, скопируйте еще эхо-сообщение

Непроверенные:

:: Q:\Test\2019\01\06\SU_1390824.cmd
@ECHO OFF

:: Adjust location of list
Set "theList=C:\2. List\List.txt"
:: Source dir
Set "theSource=C:\2. Files\"
:: Target dir
Set "theDestination=C:\2. Found"

For /R "%theSource%" %%A IN (*) DO For /F "delims=_" %%B in ("%%~nA") DO ( 
    ECHO:%%B|FINDSTR /XG:"%theList%" >nul 2>&1 && (
        COPY "%%~fA" "%theDestination%\%%~nxA"
    )||(
        Echo Not in theList: %%B , %%A
    )
)
Echo Done^!
Pause 
Exit /B

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .