На самом деле sed -n '/pattern/{n;p}' filename
выйдет из строя, если pattern
соответствует continuous
линиям:
$ seq 15 |sed -n '/1/{n;p}'
2
11
13
15
Ожидаемые ответы должны быть:
2
11
12
13
14
15
Мое решение:
$ sed -n -r 'x;/_/{x;p;x};x;/pattern/!s/.*//;/pattern/s/.*/_/;h' filename
Например:
$ seq 15 |sed -n -r 'x;/_/{x;p;x};x;/1/!s/.*//;/1/s/.*/_/;h'
2
11
12
13
14
15
Объясняет:
x;
: в начале каждой строки из ввода используйте x
для обмена содержимым в pattern space
& amp; hold space
. /_/{x;p;x};
: если pattern space
, который фактически является hold space
, содержит _
(это только indicator
, указывающий, соответствует ли последняя строка pattern
или not), затем используйте x
для обмена фактическим содержимым current line
на pattern space
, используйте p
для печати current line
и x
для восстановления этой операции. x
: восстановить содержимое в pattern space
и hold space
. /pattern/!s/.*//
: если current line
НЕ соответствует pattern
, это означает, что мы НЕ должны напечатайте следующую строку ниже, затем используйте команду s/.*//
, чтобы удалить все содержимое в pattern space
. /pattern/s/.*/_/
: если current line
соответствует pattern
, это означает, что мы должны напечатать следующую строку ниже , тогда нам нужно установить indicator
, чтобы сообщить sed
распечатать строку NEXT, поэтому используйте s/.*/_/
, чтобы заменить все содержимое в pattern space
на _
(вторая команда будет использовать его, чтобы судить, если последняя строка соответствует pattern
или нет). h
: перезаписать hold space
с содержимым в pattern space
; то содержание в hold space
равно ^_$
, что означает, что current line
соответствует pattern
или ^$
, что означает, что current line
НЕ соответствует pattern
. s/.*/_/
, pattern space
НЕ МОЖЕТ соответствовать /pattern/
, поэтому s/.*//
ДОЛЖЕН быть выполнен! есть именно этот пример на wiki в http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject .
Хотя совсем недавно я предпочитал использовать @classmethod для этого вместо того, чтобы переопределять конструктор, поскольку явный лучше, чем неявный, также проще:
user.email = Email.as_unique('foo@bar.com')
(я на самом деле собираюсь обновить wiki, чтобы более полно представить варианты использования здесь)
Я думаю, что это не лучший способ достичь этого, поскольку он создает зависимость вашего конструктора от глобальной переменной session
, а также неожиданно изменяет поведение конструктора (ожидается, что new
возвращает new в конце концов). Если, например, кто-то использует ваши классы с двумя сеансами параллельно, код будет терпеть неудачу, и ему придется выкопать код, чтобы найти ошибку.
Я не знаю никакой «sqlalchemy», способ достижения этого, но я бы предложил создать функцию createOrGetAccountModel
, подобную
def createOrGetAccountModel(**kw):
if len(kw) and "name" in kw:
x = session.query(AccountModel).filter_by(name=kw["name"]).first()
if x: return x
return AccountModel(**kw)
__new__
вводит в заблуждение. Если вы напишете x=SomeClass()
, все ожидают, что x
станет новым объектом ...
– MartinStettner
20 November 2012 в 22:36