次の行にパターン2が含まれていない場合は、パターン1に一致する行を印刷します。

次の行にパターン2が含まれていない場合は、パターン1に一致する行を印刷します。

次の行にbarが含まれていない場合は、fooを含む行と一致させたいと思います。したがって、以下を含むファイルが提供されます。

1 foo 1 
foo 2
baz bar bap

印刷のみです1 foo 1。私は/foo(?!.*\n.*bar)/それが動作するように否定的な予測を使用しました。https://regex101.com/r/ZMZsiN/1しかし、grepとperlを使用してコマンドラインで使用することはすべて失敗しました。 Perl、sed、awk、またはPythonでgrepまたは1行ステートメントを使用するすべてのソリューションは素晴らしいでしょう。 Chatgptが失敗しました。

試してみる:

$grep -Pwe 'foo(?!.*\n.*bar)' testfile
1 foo 1 
foo 2
$perl -wnl -e  /'foo(?!\n.*bar)/ and print' testfile
1 foo 1 
foo 2
$perl -ne 'print if /foo/ && ($_ = <>) !~ /bar/' testfile
foo 2

最後は、chatgptが提供するものに基づいており、近いですが、私のperlfuはまだ問題を特定するのに十分ではありません。

ベストアンサー1

grepまたは、一度にperl -n1行だけを処理するため、正規表現は1行の内容のみと一致します(行区切り文字はまたは grepperlは含まれません-l)。

複数pcregrep行モードと。-Pgrep-M

pcregrep -M '\bfoo\b(?!.*\n.*\bbar\b)'

必要に応じて一致する項目にさらに行をインポートすることに加えて、複数行モードは項目の開始と終了だけでなく、すべての行の開始と終了で一致するフラグ(暗黙的に)を有効にpcregrepします。m(?m)^$いいえこのフラグを有効にすると、改行文字が一致しないことを意味しsます。.

\b単語bの境界-w役に立つところに単語の境界を置かない)。

を使用すると、perl -n正規表現がファイル全体で一致することができないようにレコード区切り文字を設定できます。

perl -0777 -ne '
  print for m{^.*\bfoo\b.*\n(?!.*\bbar\b)}mg'

標準のUnixツールボックスを使用することは可能ですsedが、標準にはsed単語境界演算子がないため、不器用な回避策が必要です。

sed -n '/^\(.*[^[:alnum:]_]\)\{0,1\}foo\([^[:alnum:]_].*\)\{0,1\}$/ {
          $!N
          /\n\(.*[^[:alnum:]_]\)\{0,1\}bar\(.*[^[:alnum:]_]\)\{0,1\}.*$/!P
          D
        }'

おすすめ記事