Я думаю, что моя JREPL.BAT regular expression text processor может быть большой помощью. Это гибридный JScript/пакетный скрипт, который запускается изначально на любом компьютере Windows с XP.
Обширная документация доступна при запуске jrepl /?
из командной строки. Вы можете использовать jrepl /? | more
, чтобы получить помощь по одному экрану за раз. Но моя консоль сконфигурирована с большим выходным буфером, поэтому я могу прокручивать вверх, чтобы увидеть предыдущий вывод, поэтому мне не нужно БОЛЬШЕ.
Я считаю, что следующее делает в значительной степени то, что вы хотите. Он анализирует первую и последнюю строки указанного текстового файла и распечатывает список смещений столбцов в каждой строке с разделителями-запятыми. Если он обнаруживает недопустимый символ или что-то иное, чем два пробела между каждым столбцом, то он включает в себя вывод ERROR. Я изменил вывод, чтобы исключить положение двух разделителей пробелов.
Следующая команда должна запускаться из командной строки, если у вас есть JREPL.BAT в папке, включенной в ваш PATH.
jrepl "([a-zA-Z0-9=^?\\/%;]+)(?: )?|.+" "','+($off+1)+'-'+($off+$2.length)|' ERROR'" /c /j /t "|" /jbegln "skip=(ln!=1&&ln!=cnt)" /jendln "$txt=skip?false:$txt.slice(1)" /f test.txt
Вот выход для вашего текстового файла образца:
1-10,13-17,20-38,41-48
1-10,13-17,20-38,41-48
Если поместить команду в пакетном сценарии, то вы должны использовать ВЫЗОВ JREPL, в этом случае проценты должны быть в два раза убежали.
call jrepl "([a-zA-Z0-9=^?\\/%%%%;]+)(?: )?|.+" "','+($off+1)+'-'+($off+$2.length)|' ERROR'" /c /j /t "|" /jbegln "skip=(ln!=1&&ln!=cnt)" /jendln "$txt=skip?false:$txt.slice(1)" /f test.txt
Как это работает
/f "test.txt"
указывает исходный файл, в данном случае «test.txt»
/c
подсчитывает количество строк в файле и сохраняет значение в переменной cnt
,
/jbegln ...
отключает поиск и замену, если текущая строка равна 1 или cnt, установив skip
в значение true.
/jendln ...
отключает печать из текущей строки, если skip
истинно, в противном случае удаляет начальную запятую с выхода.
/j
рассматривает заменяемую строку как код JScript.
/t "|"
рассматривает строки поиска и замены как похожие списки выражений, разделенные |
. Первое выражение замены используется с первым поисковым выражением, а второе выражение замены используется со вторым поисковым выражением. Поиски обрабатываются слева направо, поэтому второе выражение проверяется только в том случае, если первое не удалось совместить.
Первый аргумент - список выражений поиска.
Второй аргумент - это список замещающих выражений.
Поиск 1: Поиск допустимого столбца с одним или несколькими допустимыми символами, необязательно сопровождаемыми ровно двумя пробелами. Обратите внимание, что первому поисковому выражению присваивается $ 1, поэтому захваченное выражение в круглых скобках (фактический столбец данных) становится $ 2 вместо $ 1.
Замена 1: запятая, за которой следует смещение совпадения (на основе 0) + 1, за которым следует тире, за которым следует смещение совпадения + длина захваченного выражения.
Поиск 2: Ищет строку из любых символов.
Замена 2: строка "ERROR".
Ваш ожидаемый результат неверен - вам не хватает позиции одного из разделителей. Правильный результат: «1-10,11-12,13-17,18-19,20-38,39-40,41-48'. Но я не понимаю, почему вам нужна позиция разделителей, поскольку они не содержат данных. Это может привести к запутыванию, если столбец данных имеет длину два. – dbenham