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=(значение меняется)
строка
строка
|
Freddy1984, давайте начнём как обычно — Вы упакуете файл в архив и приложите к сообщению.
|
Freddy1984 |
15-08-2019 14:58 2884189 |
Цитата:
Цитата Iska
Вы упакуете файл в архив и приложите к сообщению. »
|
прикрепил
|
Freddy1984, так может лучше и искать и удалять именно строку с «SetREV=»?
|
Freddy1984 |
15-08-2019 16:47 2884223 |
Цитата:
Цитата Iska
так может лучше и искать и удалять именно строку с «SetREV=»? »
|
в том то и дело что нет, в моём случае так не выйдет, так как SetREV= лишний ТОЛЬКО перед VER:1.10.50=
Во всех остальных случаях эти SetREV= не трогать. Так как в этом же текстовом файле есть и другие позиции, при которых должно быть присутствие SetREV=
|
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 |
Я благодарю Вас. А может вы в курсе как на powershell это сделать?
|
Цитата:
Цитата 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
Если же, предыдущая строка, это любой текст, тогда шаблон регэкспа необходимо будет исправить на такой: »
|
Супер! Вопрос закрыт.
|
YuS_2, а почему в первом шаблоне именно «[^\n]», а не просто «.», ведь точка и означает «Any except \n (new line)»? Это просто вопрос, ежели что.
Цитата:
Цитата Freddy1984
в том то и дело что нет, в моём случае так не выйдет, так как SetREV= лишний ТОЛЬКО перед VER:1.10.50=
Во всех остальных случаях эти SetREV= не трогать. Так как в этом же текстовом файле есть и другие позиции, при которых должно быть присутствие SetREV= »
|
Выйдет. Причём искать следует именно строку, начинающуюся на SetREV=, находящуюся перед строкой, начинающейся на VER: <цифры>. <цифры>. <цифры>=.
|
Цитата:
Цитата 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) удалять то это согласен, тоже верно.
Но это по факту всё тоже что я описал выше, только вид сбоку :)
|
YuS_2, спасибо, Ваша мысль понятна. Только точки я бы-таки заэкранировал.
Цитата:
Цитата Freddy1984
ну, в общим то если искать строку именно перед VER:<цифры> и потом её (SetREV) удалять то это согласен, тоже верно. »
|
Не «тоже верно», а именно так надо делать, и именно так и было сделано. В противном случае при повторном запуске кода мы получим удаление совсем не того, что требовалось.
|
Цитата:
Цитата 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"
То есть перед дозаписью возможно как то организовать проверку наличия конкретной предыдущей строки? И если строка отсутствует, до дописать своё.
|
Цитата:
Цитата 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
|
Цитата:
Цитата 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 |
да, я разобрался, кое что упустил, прошу прощения :)
Можно тогда ещё один вопрос в догонку? :)
У меня после "$var`n`$1" в строку идёт ещё один replace, но в консоли пишет "Отсутствует выражение после ","
То есть ругается на то что после запятой идут кавычки как я понял. А эти кавычки можно как то заэкранировать? Просто пробовал по разному, но что то не выходит.. Что то типа '"$var`n`$1" '
Запускаю в пакетнике через powershell -c
|
Цитата:
Цитата Freddy1984
Запускаю в пакетнике через powershell -c »
|
запускайте пакетником скрипт
Код:
powershell -f '.\script.ps1'
меньше будет проблем
|
Freddy1984 |
27-08-2019 14:18 2885620 |
Цитата:
Цитата YuS_2
запускайте пакетником скрипт »
|
Это я в курсе :)
Просто думал что можно без отдельного ps1 обойтись. Но нет, так нет. Ок, Спасибо! :)
|
Цитата:
Цитата Freddy1984
думал что можно без отдельного ps1 обойтись. »
|
обойтись-то можно, но для этого надо увидеть сам код, потому как этого:
Цитата:
Цитата Freddy1984
У меня после "$var`n`$1" в строку идёт ещё один replace, но в консоли пишет "Отсутствует выражение после "," »
|
недостаточно для понимания того, в чем проблема
|
Freddy1984 |
27-08-2019 20:31 2885688 |
Цитата:
Цитата YuS_2
недостаточно для понимания того, в чем проблема »
|
Я разобрался.
На всякий случай может кому когда то понадобится:
"$var`n`$1" надо заковывать аж в тройные кавычки, если вдруг у кого то (как у меня например) возникнет желание запускать скрипт PS в пакетнике :)
|
Время: 14:09.
© OSzone.net 2001-