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

Я пишу пакетный файл. часть программы будет сравнивать список файлов в «исходной» папке. С содержимым списка в текстовом файле.

Я перебираю каждый файл в папке и ищу его имя файла в текстовом файле, используя FINDSTR.

Все работает до тех пор, пока в исходной папке нет имени файла, которого нет в текстовом файле.

код findstr:

for /f %%o in ('findstr %name% old.txt') do (
    echo o=%%o >> result.txt
    if %%o==%name% (
        echo %name% exists
    ) ELSE (
        echo %name% does not exists
    )
)

Опять же, проблема возникает, когда FINDSTR ищет имя файла, которого нет в текстовом файле.

когда он достигает этой точки, он выводит переменную %%o как «%o» и ничего не выводит. Таким образом, он ничего не отправляет в results.txt.

Это не вызовет изменения ERRORLEVEL, но и ничего не выведет. Я попытался вывести уровни ошибок, но они также пусты. Я просто не понимаю, что делает FINDSTR в этом случае.

ПОЛНЫЙ пакетный файл: (это мой первый файл. Простите за любые ошибки)

  ::return the raw (/b) list of files 
  FORFILES /p %~dp0source\ /s /m "*.cr2" /C "cmd /c echo @path" > new.txt

  ::pull file path for each file and send to subroutine
  for /f %%n in ('FORFILES /p %~dp0source\ /s /m "*.cr2" /C "cmd /c echo @path"') do (

    call :dequote %%n

  )

::subroutine for removing quotes 
::and returning the filename, extension, and path
:dequote
set fullPath=%~f1
set fileName=%~n1
set fileExt=%~x1
set filePath=%~dp1
set name=%fileName%& set npath=%filePath%& set ext=%fileExt%& set fpath=%fullPath%
echo %fpath%
echo %npath%
echo %name%
echo %ext%

for /f %%o in ('findstr %name% old.txt') do (
    echo o=%%o >> result.txt
    if %%o==%name% (
        echo %name% exists
    ) ELSE (
    echo %name% does not exists
    )
)

Это происходит только с последним именем файла, отправленным на findstr. Любые предложения или направления будут очень признательны. Я пробовал и читал все, что попадалось под руку.

Спасибо за уделенное время.


ОБНОВЛЕНИЕ: 9-9-15

Вот рабочий окончательный пакетный файл, который я создал с помощью справки на этой странице. Он создает горячую папку, которая будет редактировать любые новые файлы, добавленные в нее, пока вы не остановите запуск скрипта:

  :start

  :: return the raw (/b) list of files and full path to source text
  FORFILES /p %~dp0source\ /s /m "*.cr2" /C "cmd /c echo @path" > source.txt
  IF %ERRORLEVEL% EQU 1 goto :start

  ::join new and old data, return only what is shared in common (/g)
  findstr /I /L /G:"source.txt" "output.txt" > found.txt
  IF %ERRORLEVEL% EQU 1 copy /y source.txt notFound.txt

  ::join found file names and source filenames, return those that do not have a match
  findstr /I /L /V /G:"found.txt" "source.txt" >> notFound.txt
  IF %ERRORLEVEL% EQU 2 echo error no match

  ::for each line of notFound.txt, dequote and break apart
  for /f %%n in (notFound.txt) do (
    echo n=%%n
    call :dequote %%n
  )

  :dequote
  set fullPath=%~f1
  set fileName=%~n1
  set fileExt=%~x1
  set filePath=%~dp1
  set name=%fileName%& set npath=%filePath%& set ext=%fileExt%& set fpath=%fullPath%
  echo %fpath%
  echo %npath%
  echo %name%
  echo %ext%

  cd %nPath%
  if NOT [%1]==[] (
    echo converted %name%
    convert -negate -density 600 -colorspace gray flatField.cr2 %name%%ext% -compose Divide -composite %name%.tif
    move %name%.tif %~dp0output
    cd %~dp0
    del notFound.txt
    copy /y source.txt output.txt
    ) ELSE (
     echo end of batch else
     cd %~dp0
  )

person joacampb    schedule 29.08.2015    source источник
comment
Причина, по которой вы не видите изменения уровня ошибки, заключается в том, что возвращаемое значение mycommand в for /F ('mycommand') всегда отбрасывается. Это не относится к findstr.   -  person Harry Johnston    schedule 31.08.2015


Ответы (2)


На переменные цикла в пакетном файле следует ссылаться с помощью %%, поскольку знак процента имеет особое значение, и поэтому в пакетном файле его необходимо экранировать другим знаком процента, чтобы указать его буквально. По этой причине запуск пакетного файла с echo on в окне командной строки приводит к получению %%o в пакетном файле, отображаемом как %o при выполнении.

Команда FOR, используемая в

for /f %%o in ('findstr %name% old.txt') do

обрабатывает вывод, записанный в stdout вызванной командой findstr. Но findstr ничего не записывает в стандартный вывод, когда ищет одну или несколько строк в файле и не может найти совпадающую строку ни в одной строке файла.

Таким образом, команда for ничего не может обработать, и поэтому ни одна из команд после do в этом случае вообще не обрабатывается.

Предполагая, что файл списка содержит только имена файлов без пути, следующий пакетный файл с комментариями можно использовать для получения с 1 выполнением команды dir и всего 1 или 2 запусками консольного приложения. findstr два списка, содержащие имена файлов в найденной папке и не найденных в файле списка. Пакетный файл написан для того, чтобы не создавать пустые файлы.

@echo off
setlocal
set "ListFile=C:\Temp\List.txt"
if not exist "%ListFile%" goto NoListFile

set "SourceFolder=C:\Temp\Test"
if not exist "%SourceFolder%\*" goto NoSourceFolder

set "AllFileNames=%TEMP%\AllFileNames.txt"
set "FoundFileNames=%TEMP%\FoundFileNames.txt"
set "NotFoundFileNames=%TEMP%\NotFoundFileNames.txt"

rem Get alphabetic list of files in source folder without path.
dir /A /B /ON "%SourceFolder%" >"%AllFileNames%"

rem Find all file names in list file with a case-insensitive
rem search matching completely a file name in list file and
rem output the found file names to another list file.
%SystemRoot%\system32\findstr.exe /I /L /X "/G:%AllFileNames%" "%ListFile%" >"%FoundFileNames%"
if errorlevel 1 goto NoFileNameFound

rem Find all file names with a case-insensitive search found
rem before in all file names list and output the lines not
rem containing one of the file names to one more list file.
%SystemRoot%\system32\findstr.exe /I /L /V "/G:%FoundFileNames%" "%AllFileNames%" >"%NotFoundFileNames%"
if errorlevel 1 goto AllFileNamesFound

rem Some file names are found in list file and others not.
del "%AllFileNames%"
goto :EndBatch

:NoFileNameFound
move /Y "%AllFileNames%" "%NotFoundFileNames%"
del "%FoundFileNames%"
goto EndBatch

:AllFileNamesFound
del "%AllFileNames%"
del "%NotFoundFileNames%"
goto EndBatch

:NoListFile
echo %~f0:
echo Error: No list file %ListFile%
goto EndBatch

:NoSourceFolder
echo %~f0:
echo Error: No folder %SourceFolder%

:EndBatch
endlocal

Чтобы понять, какие команды используются и как они работают, откройте окно командной строки, выполните в нем следующие команды и внимательно прочитайте все страницы справки, отображаемые для каждой команды.

  • del /?
  • dir /?
  • findstr /?
  • goto /?
  • if /?
  • move /?
  • set /?
person Mofi    schedule 30.08.2015
comment
это было невероятно полезно. Я смог хорошо следовать вашим комментариям и разработать пакетный файл, который выполняет то, что мне нужно. Я обновлю свой окончательный код выше. Благодарность! - person joacampb; 09.09.2015

Это метод, чтобы дать вам список имен файлов, которые не существуют в file.txt

@echo off
cd /d "c:\folder\to\check"
for %%a in (*) do findstr /i "%%~nxa" "file.txt" >nul || echo "%%a" is missing
pause

Он использует %%~nxa вместо %%a в случае, если в какой-то момент используются подкаталоги.

person foxidrive    schedule 30.08.2015