Войти

Показать полную графическую версию : Функция сравнения и копирования


Vurdalak120
27-12-2016, 12:04
Доброго времени суток!

Такая задача:
в папке (допустим folder) имеется файлы (например с расширением .bat & .txt) с одинаковыми именами, необходимо файлы с одинаковыми именами (т.е. 1.txt и 1.bat) перенести в другую папку (допустим folder_to), а те файлы которые, у которых не найдётся "родственной души" остались не тронутыми.

Что было предпринято:
пытался задать две переменные, а вот как их сравнить - я не имею не единого понятия. Может конвеер надо организовать?

*********************************************
@echo off

cd C:\Users\Z\Desktop\test\test1\

set var=
set /p var="Vvod: "

for %%i in (%var%.txt) do (echo %%i)
for %%e in (%var%.bat) do (echo %%e)
:set1

set /p var1="Comand: "
%var1%
goto :set1

pause
*********************************************

Iska
27-12-2016, 13:39
Попробуйте так (не проверялось):
@echo off
setlocal enableextensions enabledelayedexpansion

set sSourceFolder=c:\Folder
set sDestFolder=c:\folder_to

if exist "%sSourceFolder%\." (
if exist "%sDestFolder%\." (
for /f "usebackq delims=" %%i in (
`2^>nul dir /b /a:-d "%sSourceFolder%\*.bat"`
) do if exist "%sSourceFolder%\%~ni.txt" (
echo move "%sSourceFolder%\%~i" "%sDestFolder%\"
echo move "%sSourceFolder%\%~ni.txt" "%sDestFolder%\"
)
) else (
echo Can't find destination folder [%sDestFolder%].
exit /b 2
)
) else (
echo Can't find source folder [%sSourceFolder%].
exit /b 1
)

endlocal
exit /b 0
Для реального применения уберите echo.

megaloman
27-12-2016, 15:50
@Echo Off

Set "InBox=Z:\Box_In"
Set "OutBox=Z:\Box_Out"

FOR /F "usebackq delims=" %%f IN (`Dir "%InBox%\*.*" /B /A:-D /O:N 2^>nul`) DO (
If Exist "%InBox%\%%f" (
FOR /F "usebackq skip=1 delims=" %%i IN (`Dir "%InBox%\%%~nf.*" /B /A:-D /O:N 2^>nul`) DO (
If Exist "%InBox%\%%i" Move /Y "%InBox%\%%~nf.*" "%OutBox%\" >nul
)
)
)
Идея решения: во внешнем цикле получаем список файлов командой Dir, во внутреннем цикле для каждого полученного имени получаем снова список файлов полученного имени для всех расширений с пропуском первого. Если файл с полученным именем один, то внутренний цикл не работает, иначе переносятся все файлы с полученным именем для всех расширений.

alpap
27-12-2016, 17:42
@echo off
set "di=papka_in"
set "do=papka_out"
for /f "delims=" %%a in ('2^>nul dir/a-d/b "%di%"') do set/a "$_%%~na+=1"
for /f "tokens=2* delims=_=" %%a in ('set $_') do if %%b gtr 1 >nul move/y "%di%\%%a.*" "%do%\"
exit

Iska
27-12-2016, 18:00
«Все работы хороши, выбирай на вкус»™ ;).

megaloman, а зачем здесь:
If Exist "%InBox%\%%f" ( »
проверять существование файла? Он ведь в любом случае существует, поскольку получен посредством dir.

megaloman
27-12-2016, 18:15
Iska, Я не очень понимаю, как работает команда For+Dir. Когда-то очень давно у меня создалось впечатление, что результат выполнения Dir из-под For попадает в некий буфер, и For уже берёт список файлов из этого буфера, а не из реального наличия файла, если по какой-то причине файлы успели удалиться, как здесь, то можно впасть в ошибку. Поэтому я перестраховываюсь. Возможно, это ересь и я не прав. На моём тестовом примере после удаления этого If ничего не изменилось.

alpap, тра ля ля
тра ля ля.bat
тра ля ля.dfx
тра ля ля.doc
тра ля ля.txt
тра ля ля.xls
Для этих файлов ваш алгоритм не работает.

Iska
27-12-2016, 18:32
что результат выполнения Dir из-под For попадает в некий буфер, и For уже берёт список файлов из этого буфера »
Именно так. Как раз для того и делают цикл разбора по for /f, если внутри цикла перебора for количество файлов может измениться.

А! Понял, дошло: Вы ведь перебираете именно все файлы, а я перебирал только по маске *.bat. Вопрос снимается.

alpap
27-12-2016, 23:18
Для этих файлов ваш алгоритм не работает »
Да, пробел недопустим, разве тогда так, проверил на разных именах и сочетаниях:

@echo off
set "di=papka_in"
set "do=papka_out"
for /f "delims=" %%a in ('2^>nul dir/a-d/b "%di%"') do set "name=%%~na"& call set/a "$:%%name: =_%%+=1"
for /f "tokens=2* delims=:=" %%a in ('set $:') do set "name=%%a"& if %%b gtr 1 cmd/v/c move/y "%di%\!name:_= !.*" "%do%\"
exit

megaloman
28-12-2016, 00:28
alpap, Ку,ку.
Ку,ку.bat
Ку,ку.dfx
Ку,ку.doc
Ку,ку.txt
Ку,ку.xls

Вы чародей, я с восторгом иной раз разбираю идеи Ваших решений. Я делаю всё прямолинейнее и тупее. Поэтому пристрастно отнёсся к этому Вашему коду. Хотя, наверное, можно всегда подобрать данные, способные одурачить любую программу

alpap
28-12-2016, 02:57
Этому варианту что помешает?

@echo off
set "di=papka_in"
set "do=papka_out"
for /f "delims=" %%a in ('2^>nul dir/a-d/b "%di%"') do 2>nul dir/a-d/b "%di%\%%~na.*"|>nul find/v "%%~xa" && if exist "%di%\%%a" >nul move/y "%di%\%%~na.*" "%do%\"
exit

megaloman
28-12-2016, 14:45
alpap, Файл с именем типа aaa (то есть без расширения) переносит, хотя пары ему нет.

@Echo Off

Set "InBox=Z:\Box_In"
Set "OutBox=Z:\Box_Out"

FOR /F "usebackq delims=" %%f IN (`Dir "%InBox%\*.*" /B /A:-D /O:N 2^>nul`) DO (
If Exist "%InBox%\%%f" Call :FileMove "%InBox%\%%~nf.*"
)
GoTo :Eof

:FileMove
FOR /F "usebackq skip=1 delims=" %%i IN (`Dir %1 /B /A:-D /O:N 2^>nul`) DO Move /Y %1 "%OutBox%\" >nul &GoTo :Eof

alpap
28-12-2016, 15:40
то есть без расширения »
да, такое дело есть, естественно, сравнение в find именно по расширению.

megaloman,
склонен считать Ваш последний вариант самым удачным для данной задачи, беру в копилку - Спасибо!




© OSzone.net 2001-2012