grep は、複数の正規表現のすべての項目と一致します。

grep は、複数の正規表現のすべての項目と一致します。

SQLステートメントから接続の一部としてすべてのホスト変数を抽出する必要があります。入力例:

select * from table where :first-var || :second-var

ここから「first-var」と「second-var」を抽出する必要があります。

次の方法を使用して、それらのいずれかを一致させることができます。

grep -o -E ':\S+\s+\|\|'

':first-var ||'と一致

grep  -o -E '\|\|\s+:\S+'

マッチ '|| :2番目の変数

ただし、これら2つの式を交互のパターンに結合すると、1つの結果のみが返されます。

grep -o -E '\|\|\s+:\S+|:\S+\s+\|\|'

コマンドを複数のパターンに分割しても、1つの結果のみが一致します。

grep -o -E -e '\|\| :second-var' -e ':first-var \|\|'

疑う次は2つの結果を返すので、最初の一致の後にパイプシンボルが「ランスアウト」されます。

grep -o -E -e '\| :second-var' -e ':first-var \|'

すべての一致をどのように取得できますか?接続記号は出力の一部である必要はありません。この例では、「first-var」と「second-var」にのみ興味があります。

答え1

問題は、一度見つかったら、:first-var ||残りの|| :second-varテキストが消えることです。grep -o重ならない線部分のみ印刷できます。

次のことができます。

$ perl -lne 'print for /:\S+\s+\|\|/g, /\|\|\s+:\S+/g' file
:first-var ||
|| :second-var

(すべての:var ||sはsの前に印刷されます|| :var。)

:varまたは、部分のみが必要な場合は、grepPCREサポートでGNUを使用してください。

$ grep -Po ':\S+(?=\s+\|\|)|\|\|\s+\K:\S+' file
:first-var
:second-var

それは次のとおりです。

perl -lne 'print for /:\S+(?=\s+\|\|)|\|\|\s+\K:\S+/g'

これで、常にシェイプされた線から合計を抽出するには、:foo次のことを標準として実行できます。:baranything :foo || :bar

s='[[:space:]]\{1,\}' S='[^[:space:]]\{1,\}'
sed -n "/\(:$S\}\)$s\{1,\}||$s\(:$S\).*/{
  s//\
\1\
\2/
  s/.*\n\(.*\n\)/\1/p
}'

答え2

perl -nE 'say "$1\n$2" if /(:\S+)\s*\|\|\s*(:\S+)/'

答え3

複雑な正規表現を作成せずにファイルを2回だけ渡すだけです。

grep -o '|| *[^ ]*' file
grep -o '[^ ]* *||' file

または次の組み合わせawk

grep -o '[^ ]* *|| *[^ ]*' file | awk -F' *\\|\\| *' '{ print $1; print $2 }'

例ラインを提供

select * from table where :first-var || :second-var

これは生産します

:first-var
:second-var

関連情報