2016-10-28 2 views
-3

У меня есть файл, который иногда некорректно форматируется из-за CR/LF.Шаблон регулярных выражений для очистки данных с помощью командного файла Windows и

Хороший файл выглядит следующим образом:

R00023j Field1 Field2 .... CR/LF 
R00024n Field1 Field2 .... CR/LF 
R00025k Field1 Field2 .... CR/LF 

Но когда-нибудь У меня есть CR/LF вставляется в одном поле и это создать файл, как это:

R00023j Fiel CR/LF 
d1 Field2 .... CR/LF 
R00024n Field1 Field2 .... CR/LF 
R00025k Field1 Field2 .... CR/LF 

Мы можем считать, что у нас есть «товар» CR/LF (в конце строки) и «плохой» CR/LF (в поле).

Мы можем считать, что хороший CR/LF - это номер с RxxxxxY сразу после него, на следующей строке. Все остальные CR/LF являются плохими и должны быть заменены на . (точка).

x: цифра
Y: письмо

Как можно добиться очистки данных файлов с помощью пакетного файла Windows, и RegEx?

+0

Пожалуйста, поделитесь, что вы пробовали до сих пор! – aschipfl

+0

Число постоянных полей? Что такое поля separador? Дайте больше деталей. Как это сложно дать вам хороший ответ ..... – SachaDee

ответ

0

Ваша спецификация неполна - CR/LF также хороша, если она находится в самом конце файла.

У меня есть простое решение с использованием JREPL.BAT - A regex find/replace utility. JREPL - это чистый скрипт (гибридный пакет/JScript), который запускается изначально на любой машине Windows с XP. Полная документация доступна из командной строки через jrepl /?, или jrepl /?? для поисковой системы.

Все, что вам нужно, это простой однострочный ключ из командной строки. Если источник bad.txt, и вы хотите создать good.txt, то:

jrepl "\r?\n(?=.)(?!R\d{5}[a-z])" "." /i /m /f bad.txt /o good.txt 

Вы можете перезаписать исходный файл с помощью /o -:

jrepl "\r?\n(?=.)(?!R\d{5}[a-z])" "." /i /m /f file.txt /o - 

Используйте ВЫЗОВ JREPL, если вы поместите команду внутри пакетного скрипта.

Обратите внимание, что вы должны искать по строкам, поэтому необходимо использовать опцию /M, которая загружает весь файл в память. Это ограничивает размер файла, который может быть обработан. Я считаю, что предел составляет от 1 до 2 гигабайт.

0

должен работать, если нет специальных символов в файл и дополнительные CRLF не больше появляться внутри RxxxxxY

@echo off 
setlocal enabledelayedexpansion 
for /f "delims=" %%a in (t.txt) do (
    echo %%a|findstr /b "R[0-9][0-9][0-9][0-9][0-9][a-z]">nul && (
    echo(!line! 
    set line=%%a 
) || (
    set line=!line!%%a 
) 
) 
echo %line% 

Когда вы должны адаптировать его к вашим потребностям, пожалуйста, обратите внимание на некоторые findstr limitations

0

Хотя вы не проявляли никаких усилий, я решил предоставить сценарий, потому что задача под рукой, по-видимому, довольно сложна для меня; так что здесь мы идем (код contans много пояснительных замечаний, так что не пугайтесь):

@echo off 
setlocal EnableExtensions DisableDelayedExpansion 

rem // Define constants here: 
rem /* Regular expression string for `findstr` command (to match `RxxxxxY`); 
rem do not state `[a-z]` expression due to a nasty flaw of `findstr`!: */ 
set "_SEARCH=R[0-9][0-9][0-9][0-9][0-9][abcdefghijklmnopqrstuvwxyz]" 
set "_REPLAC=." & rem // (character which each bad CR+LF is to be replaced by) 

rem // Enumerate all files provided by command line arguments: 
for %%F in (%*) do (
    rem /* Store paths of input and output files; to overwrite input files, 
    rem set `FILENEW` to `%%~fF` also: */ 
    set "FILEOLD=%%~fF" 
    set "FILENEW=%%~dpnF_NEW%%~xF" 
    rem // Initialise buffer for concatenated line strings: 
    set "LBUF=" 
    rem // Read currently iterated file line by line (ignoring empty lines): 
    setlocal EnableDelayedExpansion 
    for /F "delims=" %%L in ('type "!FILEOLD!" ^& ^> "!FILENEW!" rem/') do (
     endlocal 
     rem // Store current line string: 
     set "LINE=%%L" 
     setlocal EnableDelayedExpansion 
     rem/ Double " due to pipe: 
     set "LINE=!LINE:"=""!" 
     rem /* Loop iterating once only over the current line with quotation 
     rem marks doubled in order to avoid trouble with the pipe later; 
     rem this allows disabling delayed expansion which might cause 
     rem trouble with pipes too in case `!` or `^` characters appear: */ 
     for /F "delims=" %%K in (^""!LINE!"^") do (
      endlocal 
      rem /* Feed line string into `findstr` command using a pipe: 
      rem for case-insensitivity, add switch `/I` to `findstr`: */ 
      echo("%%~K"| > nul findstr /X /R /C:\"%_SEARCH%.*\" 
      rem // Test whether `findstr` encountered a match: 
      if ErrorLevel 1 (
       rem /* No match encountered, so CR+LF was bad, hence 
       rem concatenate previous buffer with current line, 
       rem separated by the predefined character; due to a 
       rem preceding `endlocal` command, `LINE` no longer 
       rem contains the doubled quotation marks at this point; 
       rem the `for /F` loop transfers the resulting string over 
       rem the `endlocal` barrier safely: */ 
       setlocal EnableDelayedExpansion 
       for /F "delims=" %%E in (^""!LBUF!%_REPLAC%!LINE!"^") do (
        endlocal 
        set "LBUF=%%~E" 
       ) 
      ) else (
       rem /* Match encountered, so CR+LF is good, hence return 
       rem the current buffer; the `if` query avoids to output 
       rem an empty line initially: */ 
       if defined LBUF (
        setlocal EnableDelayedExpansion 
        >> "!FILENEW!" echo(!LBUF! 
        endlocal 
       ) 
       rem // Store the current line to the buffer: 
       set "LBUF=%%L" 
      ) 
     ) 
     setlocal EnableDelayedExpansion 
    ) 
    rem // Return the remaining content of the buffer finally: 
    >> "!FILENEW!" echo(!LBUF! 
    endlocal 
) 

endlocal 
exit /B 

В случае следует рассматривать шаблон поиска (RxxxxxY) регистронезависимо, просто добавьте переключатель /I к findstr команда.

Обратите внимание, что общая длина каждой (конкатенированной) линии ограничена примерно 8190 символами.

0

Спасибо всем за ваш вклад. Dbenham, вы правы, когда говорите, что моя спецификация неполна, когда вы говорите, что в конце файла CR/LF это хорошо. Спасибо за ссылку JREPL!

Я решил случай с Regex и Powershell: $ FileOut = $ fileIn -creplace '\ x0D \ x0A (?! [R] [0-9] {5} [a-z])', '. '

С FileIn чтения с опциями: -Кодирование UTF8 -raw

+0

Вместо того, чтобы оставлять комментарий «спасибо» в качестве ответа, подумайте о том, чтобы принять самый полезный ответ и оставить комментарий. –

Смежные вопросы