Как правильно расположить записи в пакетном режиме Windows? - PullRequest
0 голосов
/ 28 июня 2018

У меня есть файл s_result.txt как:

AAA,BBB,CCC
DDD,EEE
FFF,GGG
HHH,III,JJJ
...

И я пытаюсь получить sf_result.txt так:

AAA,BBB
AAA,CCC
DDD,EEE
FFF,GGG
HHH,III
HHH,JJJ
...

Я использовал скрипт, как показано ниже:

REM Transfer s_result.txt to sf_result.txt
DEL sf_result.txt
Echo. 2>sf_result.txt
for /F "tokens=1,2,3 delims=," %%a in (s_result.txt) do (
If %%c EQU [] (
ECHO %%a,%%b>>sf_result.txt
) else (
ECHO %%a,%%b>>sf_result.txt
ECHO %%a,%%c>>sf_result.txt
)
)

Вместо этого я получил этот result.txt:

AAA,BBB
AAA,CCC
DDD,EEE
DDD,
FFF,GGG
FFF,
HHH,III
HHH,JJJ
...

Как я могу получить правильный результат?

Спасибо

Ответы [ 3 ]

0 голосов
/ 28 июня 2018

Мне нравится умный подход rojo (+1).

Чтобы преодолеть последствия, которые он упоминает, я думаю о рекурсивном подходе.

:: Q:\Test\2018\06\28\SO_51073893.cmd 
@echo off & setlocal
for /f "usebackq tokens=1-2* delims=," %%A in ("test.txt") do Call :Sub "%%A" "%%B" "%%C"
Goto :Eof
:Sub
Echo %~1,%~2
if "%~3" neq "" for /f "tokens=1* delims=," %%D in (%3) do Call :Sub %1 "%%D" "%%E"

С немного измененным файлом test.txt Я получаю этот вывод:

> SO_51073893.cmd
AAA,B=B
AAA,C;C
DDD,EEE
FFF,GGG
HHH,I I
HHH,JJJ
0 голосов
/ 28 июня 2018

Там уже были хорошие ответы, предоставленные некоторыми умными подходами.
Однако я хочу придерживаться кода, который вы разместили здесь.

Основной проблемой является строка if %%c EQU [], поскольку она сравнивает третий токен с литеральной строкой []; в соответствии с вашим примером третий токен может быть CCC, JJJ или пустой строкой, поэтому условие никогда не будет выполнено.
Чтобы исправить это, вы должны написать if "%%c"=="".

Вы можете улучшить свой сценарий, выполнив одно перенаправление > в выходной файл, а не создав его заранее и добавив несколько раз; просто поместите весь цикл for /F между скобками и перенаправьте весь блок.

Итак, исправленный и улучшенный код:

rem Transfer s_result.txt to sf_result.txt
> "sf_result.txt" (
    for /F "usebackq tokens=1-3 delims=," %%a in ("s_result.txt") do @(
        if "%%c"=="" (
            echo %%a,%%b
        ) else (
            echo %%a,%%b
            echo %%a,%%c
        )
    )
)

Символ @ запрещает вывод командных эхо-сигналов тела цикла в выходной файл. Если в начале вашего скрипта есть @echo off, вам больше не нужен этот символ.

Конечно, этот код не может правильно обрабатывать строки с более чем тремя токенами.

0 голосов
/ 28 июня 2018

Если вы хотите анализировать построчно, используйте for /F. Если вы хотите разбить слово на слово в одной строке, используйте for без /F. Кроме того, в базовом цикле for Windows уже разбивает токены на запятые без кавычек без необходимости указывать разделитель. (Он также разбивает токены на пробелы, табуляции и точки с запятой.) Учитывая это, решение на самом деле довольно простое.

@echo off & setlocal

for /f "usebackq tokens=1* delims=," %%I in ("test.txt") do (
    for %%x in (%%J) do (
        echo(%%I,%%x
    )
)

Выход:

AAA, BBB
AAA, CCC
DDD, ЕЕЕ
FFF, GGG
HHH, III
HHH, JJJ

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...