Имя пользователя:
Пароль:
 | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Поиск и замена

Ответить
Настройки темы
CMD/BAT - [решено] Поиск и замена

Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать


Добрый день.
Имеется тектовый файл, размером более 5000 строк. Вида:

pl (IdPl,X,Y,TitleLine,Name,Description,idRowMetric,idPlMetric,Person) Values (26916,1000,3750,'','','11',null,NULL,1)
pla (IdPl,EncLevel,IdSection) Values (26916,2,21)
pla(IdPl,EncLevel,IdSection) Values (26916,1,1065)

Pl (IdPl,X,Y,TitleLine,Name,Description,idRowMetric,idPlMetric,Person) Values (26917,2900,3750,'','','11',null,NULL,1)
Pla(IdPl,EncLevel,IdSection) Values (26917,2,21)
Pla (IdPl,EncLevel,IdSection) Values (26917,1,1065)

Pl (IdPl,X,Y,TitleLine,Name,Description,idRowMetric,idPlMetric,Person) Values (26918,1050,3750,'','','11',null,NULL,1)
Pla (IdPl,EncLevel,IdSection) Values (26918,2,21)
Pla (IdPl,EncLevel,IdSection) Values (26918,1,1065)

Pl (IdPl,X,Y,TitleLine,Name,Description,idRowMetric,idPlMetric,Person) Values (26919,1100,3750,'','','11',null,NULL,1)
Pla (IdPl,EncLevel,IdSection) Values (26919,2,21)
Pla (IdPl,EncLevel,IdSection) Values (26919,1,1065)


Задача состоит в том, что-бы заменить все Выделенные жирным цветом значения(они меняются +1 каждую четвертую строчку), на отрицательные цифры по порядку: 26916 == -1 , 26917 == -2 , 26918 == -3 ...

Отправлено: 10:44, 18-03-2016

 

Забанен


Сообщения: 793
Благодарности: 260

Профиль | Цитировать


user689, уважаемый, Вы в своем уме? Обрабатывать файл в пять тысяч строк на командном языке - что-то из разряда утонченного извращения. PowerShell'то достаточно долго думал, к слову, решение на нем будет выглядеть примерно так:
Код: Выделить весь код
gc file | % {$a=-1;$b=0}{$_ -replace '(\d{5})', $a;$b++;if($b -eq 4){$b=0;$a+=-1}}
Наименее затратным по времени оказался Perl:
Код: Выделить весь код
perl -pe 's/(\d{5})/-($1-26915)/e' file
Чуть более затратным оказался Python, далее - Ruby. sed'ом еще не пробовал, но, нужно полагать, он немногим уступает тому же Python'у или Perl'у.
Это сообщение посчитали полезным следующие участники:

Отправлено: 19:08, 18-03-2016 | #2



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

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Ветеран


Сообщения: 1759
Благодарности: 966

Профиль | Цитировать


На PowerShell можно еще так:
Код: Выделить весь код
$a=0; (gc file.txt -read 4) | foreach { $_ -replace '\d{5}', --$a } | sc file.txt
или, если это будет "затратно", то сначала создать временный файл, а потом уже заменить им исходный.
Это сообщение посчитали полезным следующие участники:

Отправлено: 20:16, 18-03-2016 | #3


Забанен


Сообщения: 793
Благодарности: 260

Профиль | Цитировать


Foreigner, тогда уж лучше:
Код: Выделить весь код
gc file -r 4|%{$a=0}{$_ -replace '\d{5}', --$a}
Но все равно медленне Perl'а.
Это сообщение посчитали полезным следующие участники:

Отправлено: 20:36, 18-03-2016 | #4


Ветеран


Сообщения: 1759
Благодарности: 966

Профиль | Цитировать


Цитата greg zakharov:
Но все равно медленне Perl'а. »
Ничего не попишешь. А Perl какой и под какую платформу?

Отправлено: 21:07, 18-03-2016 | #5


Забанен


Сообщения: 793
Благодарности: 260

Профиль | Цитировать


В принципе, если гибридить JScript с командным языком, то:
Код: Выделить весь код
0</* :
@cscript /nologo /e:jscript "%~f0" %*&exit /b */0;
(function(file) {
  with (new ActiveXObject('Scripting.FileSystemObject')) {
    if (!FileExists(file)) {
      WScript.echo('File not found or does not exist.');
      return;
    }

    var fs = OpenTextFile(GetAbsolutePathName(file), 1);
    while (!fs.atEndOfStream) {
      var s = fs.ReadLine();
      if (s !== null) {
        WScript.echo(s.replace(/\d{5}/, "-" + (s.match(/\d{5}/)-26915)));
      }
    }
    fs.Close();
  }
}(
  WScript.Arguments.length !== 1
  ? (function() {
    WScript.echo('Usage: ' + WScript.ScriptName + ' <file>');
    WScript.echo('.e.g.: ' + WScript.ScriptName + ' E:\\sandbox\\file.txt');
    WScript.Quit(1);
  }()) : WScript.Arguments.Unnamed(0)
));
По скорости все же быстрее PowerShell'а. Правда операции над группами при замене не пракатывают, приходится еще и match задействовать.
gawk при замерах также показывает неплохой результат.
Код: Выделить весь код
gawk 'match($0,/(.*\()([0-9]{5})(,.*)/,a) {$0=a[1]"-"a[2]-26915a[3]} 1' file
Это сообщение посчитали полезным следующие участники:

Отправлено: 22:01, 18-03-2016 | #6


Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать


Спасибо за ответы!
PowerShell справился с задачей.
А как быть если в тексте встречаются дополнительные строки, количество их может быть разное, например:

pl (IdPl,X,Y,TitleLine,Name,Description,idRowMetric,idPlMetric,Person) Values (26916,1000,3750,'','','11',null,NULL,1)
pla (IdPl,EncLevel,IdSection) Values (26916,2,21)
pla(IdPl,EncLevel,IdSection) Values (26916,1,1065)
go

Pl (IdPl,X,Y,TitleLine,Name,Description,idRowMetric,idPlMetric,Person) Values (26917,2900,3750,'','','11',null,NULL,1)
Pla(IdPl,EncLevel,IdSection) Values (26917,2,21)
Pla (IdPl,EncLevel,IdSection) Values (26917,1,1065)
commit
go

...
...
...

Однако перед каждым заменяемым значением всегда присутствуют "Values ("

Отправлено: 06:34, 21-03-2016 | #7


Ветеран


Сообщения: 27449
Благодарности: 8088

Профиль | Отправить PM | Цитировать


Цитата user689:
А как быть если… »
Лучшим было бы прикладывать образец реального файла, упакованного в архив.

Отправлено: 07:15, 21-03-2016 | #8


Новый участник


Сообщения: 5
Благодарности: 0

Профиль | Отправить PM | Цитировать



Пример файла во вложении.
ttv.7z

Отправлено: 08:52, 21-03-2016 | #9


Ветеран


Сообщения: 1759
Благодарности: 966

Профиль | Цитировать


user689, Попробуйте такой вариант:
Код: Выделить весь код
$a = sls '\d{5}' ttv.txt
$b = gc ttv.txt

# $a.matches.value[0]..$a.matches.value[($a.matches.value.count-1)] |  # если версия PowerShell ниже четвертой 

$a.matches.value[0]..$a.matches.value[-1] |
foreach { $n=0 } { $b = $b -replace $_, --$n }

$b | sc ttv-new.txt

Последний раз редактировалось Foreigner, 21-03-2016 в 10:06.

Это сообщение посчитали полезным следующие участники:

Отправлено: 10:00, 21-03-2016 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » CMD/BAT - [решено] Поиск и замена

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
VBS/WSH/JS - Поиск и замена файлов. Drotik Скриптовые языки администрирования Windows 2 24-04-2014 18:07
Любой язык - Поиск и замена текста firstarey Скриптовые языки администрирования Windows 2 09-04-2013 08:44
CMD/BAT - [решено] Поиск, остановка процесса, поиск и замена файла на разных дисках Gawr33 Скриптовые языки администрирования Windows 11 23-04-2011 23:09
CMD/BAT - [решено] Поиск, остановка процесса, поиск и замена файлов на разных дисках 4zz Скриптовые языки администрирования Windows 2 21-02-2011 16:07
Разное - поиск и замена ansslecter Программное обеспечение Windows 1 06-07-2010 16:03




 
Переход