Say I have a file containing:
⟫ cat schema.rb
create_table "things", id: :serial, force: :cascade do |t|
t.string "other_column"
# ...
t.datetime "created_at"
end
create_table "users", id: :serial, force: :cascade do |t|
t.citext "email"
# ...
t.datetime "created_at", precision: 0
end
and I want to find all lines matching created_at
but not matching precision:
. That's easy enough:
⟫ grep created_at schema.rb
t.datetime "created_at"
t.datetime "created_at", precision: 0
⟫ grep created_at schema.rb | grep -v precision:
t.datetime "created_at"
but what if I want to get some context lines for the matched lines so I can see which create_table
block they occurred in? Adding a -C
/-B
flag to the final grep -v
is too late because the first grep already dropped all context lines.
⟫ grep created_at schema.rb | grep -v precision: -B3
t.datetime "created_at"
But adding it to the first grep
is too early because the grep -v
only removes its matched line, not the context lines around its matched lines:
⟫ grep created_at -B3 schema.rb | grep -v precision: -B3
create_table "things", id: :serial, force: :cascade do |t|
t.string "other_column"
# ...
t.datetime "created_at"
--
create_table "users", id: :serial, force: :cascade do |t|
t.citext "email"
# ...
Is there any way to get it to only include the context lines for the matched lines from the first grep
(or equivalently, get the grep -v
to remove the context lines around its matched lines)?
create_table "things", id: :serial, force: :cascade do |t|
t.string "other_column"
# ...
t.datetime "created_at"
Or is there another command that would do this for me?
(a simple sed
script perhaps—if it requires anything more than a simple sed
script, I may as well write it in ruby
so that it's easier to read and maintain).
awk -vRS= '/created_at/ && !/precision/' schema.rb
– steeldriver Aug 15 '18 at 17:21create_table
sections are all separated by a blank line. – Tyler Rick Aug 15 '18 at 17:28