В Windows 7, как я могу рекурсивно коснуться всех файлов в каталоге (включая подкаталоги), чтобы обновить отметку даты / времени?
Есть ли в Windows 7 механизм для достижения этой цели?
Есть несколько возможностей:
Используйте порт touch
команды Unix и просто комбинируйте find
и touch
способ Unix. Есть несколько вариантов. Чаще всего упоминаются GNUWin32, cygwin и unxutils. Менее известными, но в некотором смысле лучше, являются инструменты из служебного инструментария SFUA, которые запускаются в Подсистеме для приложений на основе UNIX, которая поставляется в комплекте с Windows 7 Ultimate Edition и Windows Server 2008 R2. (Для Windows XP можно загрузить и установить Службы для UNIX версии 3.5.) Этот инструментарий содержит большое количество инструментов TUI командной строки, от mv
и du
, через оболочки Korn и C, до perl
и awk
. Он выпускается в версиях x86-64 и IA64, а также x86-32. Программы работают в собственном POSIX-окружении Windows, а не с DLL-библиотеками эмуляторов (такими как cygwin1.dll
), наслоенными на Win32. И да, инструментарий имеет touch
и find
, а также около 300 других.
Все эти наборы инструментов имеют общеизвестный недостаток: они, конечно, запускают отдельный процесс для каждого файла, к которому нужно прикоснуться. Это не проблема со следующими альтернативами.
Используйте одну из многих собственных touch
команд Win32, которые люди написали и опубликовали. Многие из них поддерживают опции для выполнения рекурсии, без необходимости find
в Unix. (В конце концов, они нацелены на пользовательскую базу, которая ищет touch
команду, потому что она не имеет полной загрузки перенесенных команд Unix.) Одним из таких примеров является touch
Стефана Дюге, которое, как вы можете видеть, имеет опцию --recursive
.
Станьте умнее с тайными тайнами CMD. Как упоминалось в другом ответе, COPY /B myfile+,,
обновит дату последнего изменения файла, используя малоизвестный синтаксис "плюс" команды COPY
(подробнее об этом можно узнать здесь, кстати). Это, конечно, можно комбинировать с FOR /R
для рекурсивного выполнения операции, как указано в другом ответе здесь.
Используйте заменяющий интерпретатор команд и будьте менее умным и более простым, чем CMD. TCC /LE JP Software является одним из таких. Он добавляет параметр /S
к своей команде COPY
, что означает, что можно использовать COPY /S
с синтаксисом "плюс", чтобы исключить необходимость использования оболочки FOR
. Но это все еще делает жизнь излишне сложной для себя, учитывая, что TCC /LE имеет встроенную команду TOUCH, которая напрямую поддерживает параметр /S
Поскольку они доступны, я бы порекомендовал воспользоваться unxutils. Они включают команды find
и touch
которые сделают это очень легко.
После перехода в самый верхний каталог вы хотите изменить:
find . -type f -exec touch {} +
Чтобы использовать только существующие функциональные возможности Windows (ничего лишнего для установки), попробуйте один из них:
forfiles /P C:\Path\To\Root /S /C "cmd /c Copy /B @path+,,"
(рекурсивно "трогать" все файлы, начиная с указанного пути)
ИЛИ ЖЕ
forfiles /S /C "cmd /c Copy /B @path+,,"
(рекурсивно "трогать" все файлы, начиная с текущего каталога)
Я знаю, что, возможно, уже слишком поздно, но, тем не менее, я оставлю свой ответ на тот случай, если кому-то еще понадобится то же самое.
Ответ Джона Т не сработал для меня в Windows 7. После некоторых исследований я нашел эту утилиту под названием SKTimeStamp, которая отлично справляется со своей задачей.
Вот статья с более подробной информацией о том, как это работает: http://www.trickyways.com/2009/08/how-to-change-timestamp-of-a-file-in-windows-file-created-modified-and -доступ /.
Вот шаги, которые вам нужно выполнить:
Вуаля! Все ваши файлы были обновлены! Не нужно никаких утилит Unix или командных строк.
Это не удалось на Windows 7 для меня тоже. Я использовал другой синтаксис и получил его на работу:
forfiles /c "cmd /c touch @file"
Обратите внимание, я не использовал опцию recurse.
Использование powershell:
C:\> powershell (ls your-file-name-here).LastWriteTime = Get-Date
Или вы можете использовать инструменты, уже встроенные в Windows, когда у вас уже есть какой-нибудь "сенсорный" инструмент:
for /r %i in (C:\Path\To\Root\*) do @touch "%i"
ИЛИ ЖЕ
forfiles /P C:\Path\To\Root /S /C "touch @file"
(Примечание: если вы делаете это из пакетного файла и хотите использовать команду for
, убедитесь, что вы используете двойные знаки процента для ваших переменных. (Например, %%i
вместо %i
)
Ссылаясь на ответ Джона Т выше:
Я пытался понять разницу между завершением команды exec для find
с помощью \;
и `+'(я не знал о последнем).
Это было полезно: (отсюда)
-exec command ;
Выполнить команду; true, если возвращается 0 статус. Все последующие аргументы для поиска считаются аргументами команды до аргумента, состоящего из ';' встречается. Строка '{}' заменяется текущим именем файла, которое обрабатывается везде, где оно встречается в аргументах команды, а не только в аргументах, где он один, как в некоторых версиях find.
-exec command {} +
Этот вариант действия -exec запускает указанную команду для выбранных файлов, но командная строка создается путем добавления каждого выбранного имени файла в конце; общее количество вызовов команды будет намного меньше, чем количество совпавших файлов. Командная строка создается так же, как xargs создает свои командные строки. В команде допускается только один экземпляр «{}». Команда выполняется в начальном каталоге.
Рассмотрим папку c:\myfolder
содержащую 2 файла a.txt
и b.txt
find . -type f -exec touch {} +
интерпретируется как:touch a.txt b.txt
find . -type f -exec touch {} \;
интерпретируется как:touch a.txt
touch b.txt
Таким образом, # 1 намного быстрее (но также страдает от ограничения, что команда, следующая за exec
может иметь только один заполнитель {}
).
Использование PowerShell для текущего каталога и всех его подкаталогов:
dir -R | foreach { $_.LastWriteTime = [System.DateTime]::Now }
Или вы можете указать папку сразу после dir
.