Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Удаление одной предыдущей строки (http://forum.oszone.net/showthread.php?t=341823)

Freddy1984 15-08-2019 12:59 2884155

Удаление одной предыдущей строки
 
Вложений: 1
Здравствуйте! Подскажите пожалуйста как на cmd или powershell реализовать следующее:

В текстовом файле имеем:

строка
строка
set REV=1.1
VER:1.10.50=(значение меняется)
строка
строка


Надо во всём txt файле найти и удалить одну предыдущую строку перед VER:1.10.50=(значение меняется)
То есть часть строки постоянна VER:1.10.50= и далее после знака ровно, значения меняются.

Другими словами, надо просто удалять одну предыдущую строку, что бы получилось:

строка
строка
VER:1.10.50=(значение меняется)
строка
строка

Iska 15-08-2019 14:44 2884184

Freddy1984, давайте начнём как обычно — Вы упакуете файл в архив и приложите к сообщению.

Freddy1984 15-08-2019 14:58 2884189

Цитата:

Цитата Iska
Вы упакуете файл в архив и приложите к сообщению. »

прикрепил

Iska 15-08-2019 16:30 2884220

Freddy1984, так может лучше и искать и удалять именно строку с «SetREV=»?

Freddy1984 15-08-2019 16:47 2884223

Цитата:

Цитата Iska
так может лучше и искать и удалять именно строку с «SetREV=»? »

в том то и дело что нет, в моём случае так не выйдет, так как SetREV= лишний ТОЛЬКО перед VER:1.10.50=
Во всех остальных случаях эти SetREV= не трогать. Так как в этом же текстовом файле есть и другие позиции, при которых должно быть присутствие SetREV=

megaloman 15-08-2019 17:47 2884237

Freddy1984,
VBS. Путь укажИте свой
Код:

FileIn = "Z:\Box_Arc\файл\цель.txt"

RegExp = Chr(13) + "?" + Chr(10) + "?" + ".*SetREV=.*" + Chr(13) + "?" + Chr(10) + "?" + "VER:1\.10\.50="
Rep = Chr(13) + Chr(10) + "VER:1.10.50="

With CreateObject("Scripting.FileSystemObject")
    On Error Resume Next
    With .OpenTextFile(FileIn, 1)
        If Err.Number <> 0 Then
            MsgBox "Error open file " + vbCrLf + vbCrLf + FileIn + vbCrLf + vbCrLf + "Err.Number " + CStr(Err.Number) + vbCrLf + Err.Description
            WScript.Quit 1
        End If
        InTxt = .ReadAll
        If Err.Number <> 0 Then
            MsgBox "Error read file " + vbCrLf + vbCrLf + FileIn + vbCrLf + vbCrLf + "Err.Number " + CStr(Err.Number) + vbCrLf + Err.Description
            WScript.Quit 1
        End If
        .Close
        On Error GoTo 0
    End With
           
    With CreateObject("VBScript.RegExp")
        .Pattern = RegExp
        .IgnoreCase = True
        .Global = True
    If Not .Test(InTxt) Then
            MsgBox "no substrings to replace. Reg expression:" + vbCrLf + vbCrLf + """" + RegExp + """"
            WScript.Quit 1
    End If
        Result = .Replace(InTxt, Rep)
    End With
   
    With .CreateTextFile(FileIn, True)
        .Write Result
        .Close
    End With
   
End With


Freddy1984 15-08-2019 17:50 2884238

Цитата:

Цитата megaloman
VBS. »

Я благодарю Вас. А может вы в курсе как на powershell это сделать?

YuS_2 15-08-2019 19:29 2884256

Цитата:

Цитата Freddy1984
Надо во всём txt файле найти и удалить одну предыдущую строку перед VER:1.10.50=(значение меняется) »

Цитата:

Цитата Freddy1984
как на powershell это сделать? »

Допустим, что предыдущая строка, это set REV=(значение меняется), тогда код можно написать так:
Код:

(gc 'цель.txt' -enc utf8 -raw) -replace 'SetREV[^\n]*\n(?=VER:1\.10\.50=)'|
out-file 'результат.txt' -enc utf8

Если же, предыдущая строка, это любой текст, тогда шаблон регэкспа необходимо будет исправить на такой:
Код:

(gc 'цель.txt' -enc utf8 -raw) -replace '(?<=^|\n)[^\n]+\n(?=VER:1\.10\.50=)'|
out-file 'результат.txt' -enc utf8


greg zakharov 15-08-2019 21:33 2884265

С помощью sed:
Код:

sed -i "/set rev=.*/Id" input.txt
С помощью pwsh:
Код:

(sls 'set rev=.*' -notmatch .\input.txt).line

Freddy1984 15-08-2019 23:40 2884284

Цитата:

Цитата YuS_2
Если же, предыдущая строка, это любой текст, тогда шаблон регэкспа необходимо будет исправить на такой: »

Супер! Вопрос закрыт.

Iska 16-08-2019 13:53 2884342

YuS_2, а почему в первом шаблоне именно «[^\n]», а не просто «.», ведь точка и означает «Any except \n (new line)»? Это просто вопрос, ежели что.

Цитата:

Цитата Freddy1984
в том то и дело что нет, в моём случае так не выйдет, так как SetREV= лишний ТОЛЬКО перед VER:1.10.50=
Во всех остальных случаях эти SetREV= не трогать. Так как в этом же текстовом файле есть и другие позиции, при которых должно быть присутствие SetREV= »

Выйдет. Причём искать следует именно строку, начинающуюся на SetREV=, находящуюся перед строкой, начинающейся на VER:<цифры>.<цифры>.<цифры>=.

YuS_2 16-08-2019 17:54 2884382

Цитата:

Цитата Iska
а почему в первом шаблоне именно «[^\n]», а не просто «.», ведь точка и означает «Any except \n (new line)»? Это просто вопрос, ежели что. »

Т.к. текст содержит много строк, это более надежный шаблон для захвата одной строки... скажем так, это скорее привычка использовать именно такой вариант, т.к. в программах, которые использую (например, AkelPad), есть настройка поведения захвата символов точкой...
В принципе, можно и так:
Код:

(gc 'цель.txt' -enc utf8 -raw) -replace '(?-s)SetREV.*\n(?=VER:1\.10\.50=)'|
out-file 'результат.txt' -enc utf8

- это эквивалент... так что, использование такой конструкции не принципиально.

Freddy1984 17-08-2019 09:33 2884421

Цитата:

Цитата Iska
Выйдет. Причём искать следует именно строку, начинающуюся на SetREV=, находящуюся перед строкой, начинающейся на VER:<цифры>.<цифры>.<цифры »

ну, в общим то если искать строку именно перед VER:<цифры> и потом её (SetREV) удалять то это согласен, тоже верно.
Но это по факту всё тоже что я описал выше, только вид сбоку :)

Iska 17-08-2019 20:29 2884493

YuS_2, спасибо, Ваша мысль понятна. Только точки я бы-таки заэкранировал.

Цитата:

Цитата Freddy1984
ну, в общим то если искать строку именно перед VER:<цифры> и потом её (SetREV) удалять то это согласен, тоже верно. »

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

YuS_2 17-08-2019 21:50 2884505

Цитата:

Цитата Iska
Только точки я бы-таки заэкранировал. »

однозначно! это всё моя спешка помноженная на невнимательность... :(
исправлено.

Freddy1984 26-08-2019 11:19 2885472

Можно ещё вопрос?
Подскажите пожалуйста как сделать дозапись предыдущей строки?
Вроде логично что вместо replace должен быть write. Но что то не выходит..
То есть имеется:
строка
строка
set REV=1.1
VER:1.10.50=(значение меняется)
строка
строка


Если "set REV=1.1" имеется перед "VER:1.10.50=", то пропускаем, а если "set REV=1.1" перед "VER:1.10.50=" отсутствует, то перед "VER:1.10.50=" дописать "set NEW.REV=5.5"

То есть перед дозаписью возможно как то организовать проверку наличия конкретной предыдущей строки? И если строка отсутствует, до дописать своё.

YuS_2 26-08-2019 20:04 2885552

Цитата:

Цитата Freddy1984
Вроде логично что вместо replace должен быть write. »

может и логично, но неправильно :)
Нет такого оператора в данном контексте...
А код будет примерно таким:
Код:

$var = 'Set NEW.REV=5.5'
(gc 'цель.txt' -enc utf8 -raw) -replace '(?<!set rev\=1\.1[^\n]*\n)(ver:1\.10\.50=)',"$var`n`$1" |
out-file 'результат.txt' -enc utf8


YuS_2 27-08-2019 10:46 2885590

Цитата:

Цитата Freddy1984
думал что скрипт эти записи будет пропускать »

с чего бы вдруг?
Условие было таким:
Цитата:

Цитата Freddy1984
Если "set REV=1.1" имеется перед "VER:1.10.50=", то пропускаем »

Соответственно, именно так и работает шаблон регулярного выражения, т.е. если перед строкой "VER:1.10.50=" нет строки, содержащей текст "set REV=1.1", то будет добавлена строка, записанная в переменную $var

Freddy1984 27-08-2019 11:15 2885593

Цитата:

Цитата YuS_2
с чего бы вдруг? »

да, я разобрался, кое что упустил, прошу прощения :)
Можно тогда ещё один вопрос в догонку? :)
У меня после "$var`n`$1" в строку идёт ещё один replace, но в консоли пишет "Отсутствует выражение после ","
То есть ругается на то что после запятой идут кавычки как я понял. А эти кавычки можно как то заэкранировать? Просто пробовал по разному, но что то не выходит.. Что то типа '"$var`n`$1"'
Запускаю в пакетнике через powershell -c

YuS_2 27-08-2019 12:20 2885604

Цитата:

Цитата Freddy1984
Запускаю в пакетнике через powershell -c »

запускайте пакетником скрипт
Код:

powershell -f '.\script.ps1'
меньше будет проблем

Freddy1984 27-08-2019 14:18 2885620

Цитата:

Цитата YuS_2
запускайте пакетником скрипт »

Это я в курсе :)
Просто думал что можно без отдельного ps1 обойтись. Но нет, так нет. Ок, Спасибо! :)

YuS_2 27-08-2019 18:03 2885660

Цитата:

Цитата Freddy1984
думал что можно без отдельного ps1 обойтись. »

обойтись-то можно, но для этого надо увидеть сам код, потому как этого:
Цитата:

Цитата Freddy1984
У меня после "$var`n`$1" в строку идёт ещё один replace, но в консоли пишет "Отсутствует выражение после "," »

недостаточно для понимания того, в чем проблема

Freddy1984 27-08-2019 20:31 2885688

Цитата:

Цитата YuS_2
недостаточно для понимания того, в чем проблема »

Я разобрался.
На всякий случай может кому когда то понадобится:
"$var`n`$1" надо заковывать аж в тройные кавычки, если вдруг у кого то (как у меня например) возникнет желание запускать скрипт PS в пакетнике :)


Время: 14:09.

Время: 14:09.
© OSzone.net 2001-