#powershell #batch-file #cmd
#powershell #пакетный файл #cmd
Вопрос:
У меня есть требование идентифицировать файл с нулевым размером КБ в папке и записать выходные данные в текстовый файл. Ниже приведен код, который я нашел с помощью пакетного скрипта, и я хотел бы настроить его в соответствии с моим нижеприведенным требованием.
@echo off
set out=found.txt
(for /r c:myfolderfilestosearch %%F in (*.txt) do (if %%~zF LSS 1 echo %%F)) > %out%
pause
На самом деле я бы хотел создать и записать результат в файл, если и только если в указанной папке есть только один из файлов размером 0 КБ, но мой приведенный выше скрипт создает текстовый файл для каждого экземпляра, даже если файлов размером 0 КБ нет.
Я думаю, что мы можем реализовать это с помощью if else, но, как я уже сказал, я новичок и ценю, если кто-нибудь поможет в этом с помощью скрипта.
PS Я в порядке, чтобы иметь скрипт, написанный на powershell.Спасибо.
Комментарии:
1. @Joey Спасибо за редактирование сообщения, Джоуи!
2.
for %%a in (%out%) do if %%~za == 0 del %out%
(Я бы использовал== 0
илиequ 0
вместоlss 1
)3. Вы хотите записать результат, только если в папке есть файлы размером 0 КБ, или если в папке есть только файлы размером 0 КБ и никаких других файлов? Что это за «пакетный скрипт, новый для пакетного скрипта, вот мой пакетный скрипт» — тег [powershell] ?
4. @TessellatingHeckler Здравствуйте, да, я хочу записать выходные данные в файл только тогда, когда любой из файлов в папке содержит размер 0 КБ, а в папке может быть «n» файлов разного размера, но мне интересно записать файл, если какой-либо из файлов имеет размер 0 КБ. Чтобы быть более точным, я ищу это решение либо из пакетного скрипта, либо из сценария powershell, чего угодно будет достаточно. Надеюсь, я ответил.
5. Что именно является «результатом»? это путь / имя первого пустого файла в каждом каталоге или это должен быть соответствующий путь / имя каталога?
Ответ №1:
PowerShell
Get-ChildItem -Path C:myfolderfilestsearch -Recurse -Force | Where-Object { $_.PSIsContainer -eq $false -and $_.Length -eq 0 } | Select -ExpandProperty FullName | Add-Content -Path found.txt
Воссоздавать выходной файл для каждого запуска:
(Get-ChildItem -Path C:myfolderfilestsearch -Recurse -Force | Where-Object { $_.PSIsContainer -eq $false -and $_.Length -eq 0 } | Select -ExpandProperty FullName) | Set-Content -Path found.txt
Комментарии:
1. Вышесказанное полезно и работает нормально, но когда я повторно запускаю сценарий powershell, я вижу, что данные дублируются. Вместо этого, возможно ли воссоздавать файл каждый раз при повторном запуске сценария powershell?
2. обновлено примером. круглые скобки добавляются так, чтобы все данные, сгенерированные набором команд внутри них, передавались
Set-Content
только один раз. ЗамененоAdd-Content
наSet-Content
.
Ответ №2:
Дело в том, что перенаправлению все равно, записываете ли вы данные на самом деле. Файл создается в любом случае. Но вы можете избавиться от него впоследствии, если его размер равен нулю (данные не записаны)
@echo off
set out=found.txt
(for /r c:myfolderfilestosearch %%F in (*.*) do if %%~zF LSS 1 echo %%F) > %out%
for %%a in (%out%) do if %%~za == 0 del %out%
pause
(Я бы предпочел == 0
или equ 0
вместо lss
)
Ответ №3:
У вас слишком много ненужных скобок, и они вам не нужны /r
. Это работает на моей машине:
@echo off
set out=found.txt
for %%F in (c:myfolderfilestosearch*.*) do if %%~zF LSS 1 echo %%F >> %out%
pause
Обратите внимание, что если вы не укажете конкретное расположение папки дляfound.txt , он будет находиться в любой папке, в которой находится сам пакетный файл. Если вы этого не хотите, либо укажите путь к этому файлу, либо перейдите в эту папку с помощью cd
в пакетном файле:
@echo off
cd /d "C:myfolderfilestosearch"
set out=found.txt
for %%F in (*.*) do if %%~zF LSS 1 echo %%F >> %out%
pause
или
@echo off
set out="C:myfolderfilestosearchfound.txt"
for %%F in (c:myfolderfilestosearch*.*) do if %%~zF LSS 1 echo %%F >> %out%
pause
Редактировать: Используется >>
для добавления в выходной файл.
Комментарии:
1. на самом деле параграфы вокруг полного
for
цикла необходимы, чтобы не перезаписывать выходной файл при каждом поиске.2. @Ken White Спасибо, что написал выше, но на самом деле я ищу скрипт, в который я хочу записать результат found.txt файл тогда и только тогда, когда в указанной выше папке есть только один из файлов размером 0 КБ. Согласно вашему приведенному выше сценарию, похоже, что он записывает файл каждый раз, когда мы завершаем пакет. Дайте мне знать, если я чего-то здесь не хватает.
3. Не используется
>>
, который добавляется. Я должен был упомянуть об этом изменении напрямую, чтобы сделать его более очевидным. (Спасибо @LotPings за его добавление.)4. @MGM: Нет, он добавляет только файл с нулевым байтом, если он найден. Если файлы размером 0 байт не найдены, он ничего не записывает. (Я тестировал оба способа.) Если вам нужно очистить файл, созданный предыдущим запуском, удалите его в верхней части пакетного файла.
5. @KenWhite Да, вышесказанное верно, но это создает файл даже после того, как в папке нет файлов размером 0 КБ. Я хочу, чтобы файл found.txt не должен создаваться, если в папке есть какие-либо файлы размером 0 КБ и found.txt файл должен создаваться и записываться только в том случае, если в папке находятся какие-либо файлы размером 0 КБ. Надеюсь, теперь мне все ясно.
Ответ №4:
Сбор выходных данных и задержка части «запись в файл» не так просты в пакетном режиме. В любом случае проще записать выходные данные в файл и удалить файл, если вы обнаружите файл с ненулевым размером.
@echo off
set "out=found.txt"
set "allzero=y"
(for /r C:myfolderfilestosearch %%F in (*.*) do (
if %%~zF gtr 0 (
set "allzero=n"
goto :done
)
echo %%F
))>"%out%"
:done
if "%allzero%"=="n" del /q "%out%"
В PowerShell вы можете сделать это следующим образом:
$allzero = $true
$files = Get-ChildItem C:myfolderfilestosearch -File -Recurse -Force |
ForEach-Object {
if ($_.Length -gt 0) {
$allzero = $false
continue
}
$_.FullName
}
if ($allzero) {
$files | Set-Content 'found.txt'
}