その行で一致を検索し、一致しないが一致する行を含むコンテキスト行を検索するにはどうすればよいですか?

その行で一致を検索し、一致しないが一致する行を含むコンテキスト行を検索するにはどうすればよいですか?

以下を含むファイルがあるとしましょう。

⟫ 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

created_at一致するすべての行を探したいのですがいいえマッチprecision:。それは簡単です:

⟫ 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"

しかし、一致する行の一部のコンテキスト行を取得し、その行がどのブロックに表示されるかを確認するにはcreate_tableどうすればよいですか?-C最初のgrepがすでにすべてのコンテキスト行を削除しているため、最後に/フラグを追加するのは遅すぎます。-Bgrep -v

⟫ grep created_at schema.rb | grep -v precision: -B3
    t.datetime "created_at"

しかし、最初の行に追加するのは時期尚早ですgrepgrep -v一致する行だけが削除され、一致する行を囲むコンテキスト行は削除されないためです。

⟫ 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"
    # ...

最初の行に一致する行のコンテキスト行のみを含める方法はありますかgrep(または同等にgrep -v一致する行の周囲のコンテキスト行を削除します)?

  create_table "things", id: :serial, force: :cascade do |t|
    t.string "other_column"
    # ...
    t.datetime "created_at"

それともこれを行うための他のコマンドはありますか?

sedたぶん簡単なスクリプトかもしれません。シンプル sedrubyスクリプトを読みやすく保守しやすくするために作成することもできます。

ベストアンサー1

2つのコマンドを一緒にリンクすると、私がやろうとしていることは可能ではないと思いますgrep(コンテキスト行が各個々のgrepコマンドに関連付けられているため)。

否定的な見通しは、私が望むものかもしれないと思いました。これにより、これらすべてをgrep単一のコマンドで実行できます。

驚くべきことに、GNUはgrep実際に正規表現のバック/フォワードをサポートしているようです。ただし、そのオプションを使用している場合にのみ可能です--perl-regex

grep私が探していることを知らせるコマンドは次のとおりです。

⟫ grep --perl-regexp 'created_at(?!(.*precision:))' schema.rb -B3
  create_table "things", id: :serial, force: :cascade do |t|
    t.string "other_column"
    # ...
    t.datetime "created_at"

おすすめ記事