Ваш код для сохранения строк в "массиве" сломана. Вы должны увеличивать v
вместо var
.
Код для проверки дубликатов прост, но медленный. Просто пропустите существующие значения, чтобы увидеть, соответствует ли она текущей строке. Только эхо и сохранить текущую строку, если совпадение не найдено. Чем больше число уникальных линий, тем медленнее получается.
Приведенный ниже сценарий ожидает имя файла в качестве 1-го и единственного параметра
@echo off
setlocal enableDelayedExpansion
set n=0
for /f "usebackq delims=" %%A in (%1) do (
set "skip="
for /l %%N in (1 1 !n!) do if "%%A"=="!var%%N!" set skip=1
if not defined skip (
echo %%A
set /a n+=1
set "var!n!=%%A"
)
)
выше потерпит неудачу, если строка начинается с ;
, поскольку по умолчанию для опции/F EOL будет пропускать строки, начинающиеся с ;
. Это может быть исправлено с некоторым неудобным синтаксисом, который устанавливает как EOL и DELIMS ни к чему: usebackq^ delims^=^ eol^=
выше будет разрушаться и если строка содержит !
, потому что задержка расширения будет развратить значение линии, когда переменная FOR/F расширяется , Это можно устранить, тщательно включив и отключив отложенное расширение по мере необходимости.
@echo off
setlocal disableDelayedExpansion
set n=0
for /f usebackq^ delims^=^ eol^= %%A in (%1) do (
set "ln=%%A"
set "skip="
setlocal enableDelayedExpansion
for /l %%N in (1 1 !n!) do if "!ln!"=="!var%%N!" set skip=1
if defined skip (endlocal) else (
echo !ln!
set /a n+=1
for %%N in (!n!) do (
endlocal
set "var%%N=%%A"
set "n=%%N"
)
)
)
Но есть гораздо более быстрые и простые решения.
Быстрое и простое возможное чистое пакетное решение состоит в том, чтобы включить содержимое строки в имя переменной. Чтобы проверить наличие дубликатов, просто проверьте, определена ли эта переменная.
@echo off
setlocal
:: clear existing _ variables
for /f "eol== delims==" %%V in ('set _ 2^>nul') do set "%%V="
:: read and echo file, throw away duplicates (case insensitive)
:: does not work if line contains =
for /f usebackq^ delims^=^ eol^= %%A in (%1) do (
if not defined _%%A (
echo %%A
set "_%%A=1"
)
)
Существует два основных ограничения с вышеуказанным решением.
Дубликат сравнения не чувствителен к регистру, поскольку имена переменных нечувствительны к регистру.
Решение не будет правильно обнаруживать дубликаты, содержащие =
, потому что =
не может быть включен в имя переменной.
Я считаю, что решение с использованием СНП Rene является лучшим обычно применяется подход, хотя код Rene имеет следующие недостатки
Использование ВЫЗОВ значительно снижает производительность (заметные с большими файлами)
Пропущенные строки ;
Специальные символы, такие как &
|
<
>
^
вызывают проблемы
Сценарий предполагает, что существует только один пробелами маркер
Недостатки легко фиксируются:
@echo off
setlocal disableDelayedExpansion
set "old="
for /f delims^=^ eol^= %%A in ('sort %1') do (
set "new=%%A"
setlocal enableDelayedExpansion
if "!new!" equ "!old!" (endlocal) else (
echo !new!
endlocal
set "old=%%A"
)
)
Все партии решения ограничены до максимальной длины строки ~ 8191 символов.
Кроме того, все решения, указанные выше, будут пропускать пустые строки.
У меня есть код для чтения файла и установка всех строк в переменные с именем var1, var2, var3 ect. – BBMAN225