Пакет: запись строки из .txt между двойными кавычками в .txt

Я собираюсь написать пакетный файл, чтобы получить строки из текстового файла и записать только содержимое между двумя "" (двойными кавычками) в другой текстовый файл.

экв. ввод файла:

    WRITE    1,48,1,"1> MODUL 2 TYPENKONTROLLE "
    WRITE    1,56,1,"2> MODUL 6 PRAEGETIEFE    "
    Some other text...
    WRITE    1,64,1,"__________________________"

вывод файла:

    "1> MODUL 2 TYPECONTROLE   "
    "2> MODUL 6 PRAEGETIEFE    "
    "__________________________"

моя не рабочая партия:

@echo File:
set /p file=
FOR /F delims^=^" %%i in ('findstr -i -r -c:"[\"]^" %file%.txt') do (
echo %%i >> %file%strings.txt 
)

Я думаю, мне нужно что-то вроде этого:

@echo File:
set /p file=
FOR /F delims^=^" tokens^=1,2 %%i in ('findstr -i -r -c:"[\"]^" %file%.txt') do (    
echo %%i not needed!
echo %%j >> %file%strings.txt 
)

Может ли кто-нибудь помочь мне с моей проблемой?


person ZackBoom    schedule 23.03.2015    source источник
comment
Добро пожаловать в Stack Overflow Zack! Если какой-либо из приведенных ниже ответов был полезен, не забудьте отметить его как принятый. см. эту страницу, чтобы узнать, почему это важно.   -  person rojo    schedule 23.03.2015
comment
Решение rojo работает нормально. Я добавляю некоторые функции на данный момент. Я бы очень хотел использовать grep, потому что мне это нравится в Linux. но моя компания не хочет давать мне ПК с Linux, только Win x64... грустно :D   -  person ZackBoom    schedule 23.03.2015


Ответы (2)


Если вы ищете чистое пакетное решение, то, вероятно, это все, что вам нужно. Он использует неприятные escape-последовательности в параметрах FOR /F, чтобы разрешить указание " в качестве разделителя вашего токена.

@echo off
>"output.txt" (
  for /f usebackq^ tokens^=2^ delims^=^" %%A in ("input.txt") do echo "%%A" 
)

Если вы хотите убедиться, что закрывающая кавычка присутствует, вы можете добавить FINDSTR в предложение DO. FINDSTR ожидает, что кавычки будут экранированы как \".

@echo off
>"output.txt" (
  for /f usebackq^ tokens^=2^ delims^=^" %%A in ('findstr \".*\" "input.txt"') do echo "%%A" 
)

Приведенные выше решения записывают только первую строку в кавычках из любой строки. Дополнительные строки в кавычках игнорируются.

Но я обычно использую мою текстовую утилиту регулярных выражений JREPL.BAT, чтобы манипулировать текстом. Это гибридный JScript/пакетный сценарий, который изначально запускается на любом компьютере с Windows, начиная с XP.

Предполагая, что ваш PATH включает папку, содержащую JREPL.BAT, все, что вам нужно, это следующее из командной строки:

jrepl "\q.*?\q" $0 /x /jmatch /f input.txt /o output.txt

Поскольку JREPL — это пакетный сценарий, вам необходимо использовать CALL JREPL, если вы используете команду в другом пакетном сценарии.

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

jrepl "(\q.*?\q).*" $1 /x /jmatch /f input.txt /o output.txt
person dbenham    schedule 23.03.2015

Самым простым решением было бы использовать grep. Вам понадобятся бинарные файлы и зависимости. Тогда вы могли бы просто

grep -E -o "\".+\"" infile.txt > outfile.txt

чтобы получить желаемый результат.

Трудность выполнения этого в чистом пакете заключается в том, что пакет обрабатывает кавычки как разделители токенов. Некоторые строки, содержащие символы перенаправления (символ >), еще больше усложняют ситуацию. Хотя непросто рассматривать кавычки и символы > как независимые символы, это возможно.

@echo off
setlocal

>outfile.txt (
    (
        for /f "usebackq delims=" %%I in ("infile.txt") do (
            call :get_stuff_between_quotes %%I
        )
    )
)

goto :EOF
:: // END MAIN RUNTIME

:: // get_stuff_between_quotes function
:: // echoes stuff between (and including) quotation marks
:: // echoes nothing if no quotation marks in argument
:get_stuff_between_quotes
:: // use delayed expansion to prevent evaluation of >
setlocal enabledelayedexpansion
set line=%*

:: // strip everything before first quotation mark
set line=!line:*"=!

:: // if line is unchanged, it didn't contain quotation marks.
if "!line!"=="%*" endlocal & goto :EOF

:: // otherwise, re-echo the leading quotation mark + the rest of the line
echo("!line!
endlocal & goto :EOF

Хотя, по моему не столь скромному мнению, решение grep гораздо проще выполнить.

person rojo    schedule 23.03.2015