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.rbcreate_tablesections are all separated by a blank line.