Войти

Показать полную графическую версию : [решено] как бы скопировать прямо из потока?


Gennie
07-05-2009, 17:07
Задача такая. Есть туча файлов в одной директории (много тысяч и каждый день добавляются), они вперемешку, потому что разные названия, но в каждом названии есть дата.
Файлы могут иметь разные даты создания/модификации по сравнению с той датой, что вбита в название каждого из них (это ещё один сюрприз, поэтому не получится просто отсортировать в Проводнике и смотреть в конец списка). Отлавливаю список всех, подгруженных в нужную дату примерно так: dir /b /o:d|findstr /b /i %DID% |findstr %sdate%, где DID - ещё один идентификатор, а sdate - соответствующая форма даты. В результате получается просто список нужных файлов. Которые затем хочется скопировать куда-нибудь в другую директорию, и уже там с ними работать. Потому что даже PgUp - PgDown в той огромной директории нажимать устанешь, не то что мышкой пытаться что-то выловить. Насколько показывает help, команды copy и xcopy не имеют возможностей копировать с консоли, из файла или принимая source как вывод другой команды, переданной через пайплайн. Поэтому конструкции типа C:\tmp\0>dir /b|findstr 45|copy * c:\по ходу будут копировать именно * (т.е. всё как есть из этой директории), а хочется скопировать именно тот список файлов, который был получен после тщательного отбора командой выше. Во всяких юникс-шеллах есть возможность брать информацию прямо из консоли, это обозначается дефисом "-". Но в CMD такая штука не работает. А с командой FOR не очень понятно, потому что она не работает со вложенными пайплайнами, только не с перенаправляемыми командами.

Petya V4sechkin
07-05-2009, 21:09
dir /b /o:d|findstr /b /i %DID% |findstr %sdate%
Можно ведь проще:
dir /b %DID%*%sdate%*
А копирование:
copy /y %DID%*%sdate%* путь_к_папке

Iska
07-05-2009, 21:12
Примерный код пакетного файла может выглядеть наподобие:(за отсутствием исходных данных я был вынужден взять папку «%systemroot%\system32» и произвольные значения переменных окружения «DID»/«sdate», дабы была возможность воспроизвести результат работы пакетного файла).
@echo off
setlocal enabledelayedexpansion

set DID=nt
set sdate=4

pushd "%systemroot%\system32"

for /f %%i in ('dir /b /o:d ^|findstr /b /i %DID% ^|findstr %sdate%') do (
copy /y "%%i" "C:\Temp\%%i"
)

popd

endlocal
exit /b 0

Gennie, если переменные окружения «DID»/«sdate» содержат «запрещённые» символы, то, возможно, их также потребуется экранировать посредством «^».

Gennie
07-05-2009, 23:44
Iska, интересный код, завтра попробую сделать оба предложения, но у меня сомнения. Как я говорил, раньше пробовал сделать в цикле FOR пайплайн, и это не получалось, если убирал пайплайн -- всё работало. Кажется, что FOR почему-то не осиливает перенаправление вывода команд внутри себя, не знаю почему. Винда 2К, пропатченная от работы (но на cmd это вроде никак не должно влиять).

mitiya
08-05-2009, 10:11
Gennie, потоки точно работают внутри цикла. Вы вероятно просто писали | вместо ^| . Внутри цикла нужно экранировать символ | иначе интерпретатор будет думать, что это просто строка с перенаправлением и ничего работать не будет.

Gennie
11-05-2009, 21:39
О, спасибо большое! Да, я действительно не ставил экранов перед символом |.
То, что нужно, получилось с первого совета (copy с нужными параметрами), но интересно будет попробовать и более сложный вариант, для самообразования. Не успел ещё.




© OSzone.net 2001-2012