2015-10-26 6 views
1

я пытаюсь Переберите все установленные программы: создаетсяBatch сценарии: выход пуст при попытке повторить содержимое файла

wmic /output:C:\temp\InstallList.txt product get name 

for /F "tokens=*" %%G in (C:\temp\InstallList.txt) do echo %%G 

файла, но выход пуст!

+0

Не используйте WMIC и партии и вместо этого используйте PowerShell. –

ответ

0

Выход не пуст. Вывод находится в Юникоде. Используйте more для преобразования в текущую локальную кодировку.

Если вы хотите, чтобы пробелы удалены из конца строки см How to remove trailing and leading whitespace for user-provided input in a batch file?

setlocal enabledelayedexpansion 
wmic product get name | more >"C:\temp\InstallList.txt" 
for /F "skip=1 usebackq tokens=*" %%G in (`type "C:\temp\InstallList.txt"`) do (
    set S=%%G 
    set S=!S:~0,-1! 
    if "!S!" NEQ "" (echo !S!) 
) 
+0

1. Ваша вторая строка не будет работать, опция 'usebackq' отсутствует! 2. Ваша первая строка работает, хотя в выходном файле будет некоторый шум (избыточные возврат каретки); это может вызвать проблемы при чтении (например, использовать «эхо» %% G »' во второй строке, то вы заметите, что некоторые закрывающие кавычки исчезнут ...); – aschipfl

+0

Вы правы @aschipfl. Я редактировал код, чтобы изменить цикл for, а также обрабатывать посторонние \ r, которые испускает wmic. – lit

+0

Спасибо, @ Литургист! существует еще более простой и более безопасный подход, чтобы избавиться от дополнительных CR: внутри 'for/F %% G', просто поместите другой цикл' for/F 'delims = "%% F in (" %% G ") do echo "%% F"; поэтому вам не понадобится отсроченное расширение, и нет риска слишком многого; – aschipfl

0

просто могли бы сделать все это в одном

FOR /F "skip=1 delims=" %%G in ('wmic product get name') do @echo %%G 
0

Проблема формат Unicode выхода команды wmic. Следовательно, ваш файл InstallList.txt содержит много байтов 0x00, которые приводят к завершению цикла for /F.

Чтобы обойти это, захватить wmic выход с for /F цикла, поэтому он становится преобразуется в не-Unicode формат:

@echo off 
for /F "skip=1 delims=" %%G in (' 
    wmic PRODUCT GET Name 
') do echo %%G 

Опция skip=1 удаляет заголовок Name из выходного сигнала.

К сожалению, выход по-прежнему содержит некоторые тревожные артефакты (на самом деле, есть некоторые осиротые возвращения каретки). Чтобы избавиться от них, гнезда другой for /F петли:

@echo off 
for /F "skip=1 delims=" %%G in (' 
    wmic PRODUCT GET Name 
') do (
    for /F "delims=" %%F in ("%%G") do echo %%F 
) 

Конечно, вы можете разобрать ваш Юникод выходного файл InstallList.txt с for /F, но вы не можете сделать это напрямую, вам нужно использовать команду type сделать преобразование в не-Unicode:

for /F "skip=1 delims=" %%G in (' 
    type "C:\temp\InstallList.txt" 
') do rem the rest is the same as above 

Вы также можете использовать команду more для достижения этой цели, просто писать more вместо type.


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

@echo off 
setlocal EnableDelayedExpansion 
set "REPL= " 
for /F "skip=1 delims=" %%G in (' 
    wmic PRODUCT GET Name 
') do (
    for /F "delims=" %%F in ("%%G") do (
     set "LINE=%%F%REPL%" 
     set "TRNC=!LINE:*%REPL%=%REPL%!" 
     call echo %%LINE:!TRNC!=%% 
    ) 
) 
endlocal 

Что я делаю здесь является:

  • указать последовательность пространств (4 в этом примере, при условии, что каждая строка содержит меньше пространства в его части интереса) в переменной REPL;
  • , чтобы прочитать каждую строку, добавить последовательность пробелов и сохранить расширенную строку в LINE;
  • для получения фактической последовательности конечных пробелов на строку (путем поиска последовательности в REPL) и для ее сохранения в TRNC;
  • заменить фактическую последовательность пробелов каждой строки ничем, то есть усечь ее, а затем фактически вывести оставшуюся часть строки;

Конечно, вы можете это сделать и при анализе файла InstallList.txt, как описано выше.

+0

Спасибо за подробный ответ! – Ariel

+0

Лучший способ сказать «спасибо» - это upvoting ... ;-) – aschipfl

+0

Я не могу выдвигать, потому что у меня меньше 15 точек репутации ... – Ariel