Как вы можете использовать команду FIND для текстового файла, который использует CR, но не LF? - PullRequest
0 голосов
/ 21 марта 2012

Я не знаю, возможно ли это на самом деле, но у меня есть текстовый файл, который содержит несколько строк, в которых используется только символ возврата каретки (CR) ascii и не сопровождается переводом строки (LF)символ.

Моя проблема в том, что я пытаюсь использовать команду FIND для поиска строки в файле, но не могу заставить ее вернуть любую из строк с CR (она возвращает CR +LF-линии, очевидно).

Можно ли как-нибудь найти эти строки с помощью собственных командных команд?

1 Ответ

2 голосов
/ 21 марта 2012

Я полностью протестировал FINDSTR, и я знаю, что он будет обрабатывать весь файл как одну строку, если он имеет только <CR> и нет <LF>.

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


Редактировать 1

Я подтвердил (в любом случае на Vista),что FIND разрывает строки строго после <LF>, с или без <CR> перед ним.Символ <CR> просто обрабатывается как другой символ.

У вас не должно возникнуть проблем с поиском строк, в которые вставлено <CR>.Проблема будет в том, как выглядит вывод на экран.Кроме того, несколько логических строк будут обрабатываться как одна строка (те, «заканчивающиеся» <CR>).

Я создал файл test.txt со следующей структурой

1<CR><LF>
2<CR><LF>
3<CR>4<CR>5<CR><LF>
6<CR><LF>
7<CR><LF>

Изатем использовал FIND против него

FIND "2" <test.txt
-> 2

FIND "3" <test.txt
-> 5

FIND "4" <test.txt
-> 5

FIND "5" <test.txt
-> 5

FIND "6" <test.txt
-> 6

Вывод выглядит странно при поиске 3 и 4, но на самом деле это правильно.Это потому, что 3, 4 и 5 находятся на одной линии.FIND печатает всю строку, но возврат каретки приводит к тому, что 3 перезаписывается на 4, а 4 перезаписывается на 5. Это становится более очевидным, если я делаю FIND "3" <test.txt >out.txt - он создает файл длиной 7 байтов.

Вы получите в основном те же результаты, если будете использовать FINDSTR.

Вы не можете заставить FIND (или FINDSTR) разбивать строки в одиночку <CR>.Но вы можете предварительно обработать ваш файл, чтобы преобразовать одиночные символы <CR> в стандартные ограничители строки Windows, используя следующий простой гибридный скрипт.Сценарий принимает имя файла для преобразования в качестве первого и единственного параметра.

Основная часть преобразования выполняется с помощью JScript, а остальная часть - с помощью пакета.Вероятно, глупо использовать гибрид - все это можно было сделать с помощью JScript (или VBScript), но гибрид был забавным.И вы можете легко добавлять дополнительные пакетные команды, как вам удобно.Например, вы можете добавить команду FIND после MOVE, но до EXIT /B.

Предупреждение - скрипт перезаписывает исходный текстовый файл.Удалите команду MOVE, если хотите, чтобы измененная версия была отдельным файлом.

@if (@x)==(@y) @end /* harmless valid code for both batch and Jscript
::********* Batch Part **************************************************
:: This batch script calls the JScript below to normalize the end-of-line
:: for the contents of the file name passed in as parameter 1.
:: It redirects JScript to read its input from the file, and writes the
:: output to a new file. The batch script than moves the new file to 
:: replace the original.
::
:: You could put your FIND command after the MOVE and before the EXIT /B.
::
@echo off
<%1 cscript //e:jscript /nologo "%~f0" >"%~1.new"
move "%~1.new" "%~1" >nul
exit /b

*********** JScript Part **************************************
* This little script reads stdin, normalizes the end-of-line,
* and writes the result to stdout
*
* <CR><LF> -> no change
* <LF> without preceding <CR> -> <CR><LF>
* <CR> without following <LF> -> <CR><LF>
*/
while (!WScript.StdIn.AtEndOfStream) {
  WScript.StdOut.WriteLine(WScript.StdIn.ReadLine().replace( /\r/g, "\r\n" ) );
}

Редактировать 2

Я простоЯ понял, что существует совершенно неразрушающий метод поиска «строк», оканчивающихся на <CR>, если я просто немного изменю свой скрипт выше.Помимо внесения необходимых изменений, я исключил комментарии.

Скрипт теперь принимает 2 аргумента: "searchString", "fileName"

@if (@x)==(@y) @end /* harmless valid code for both batch and Jscript
::********* Batch Part **********************************************
@echo off
<%2 cscript //e:jscript /nologo "%~f0" | find "%~1"
exit /b

*********** JScript Part *******************************************/
while (!WScript.StdIn.AtEndOfStream) {
  WScript.StdOut.WriteLine(WScript.StdIn.ReadLine().replace( /\r/g, "\r\n" ) );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...