次の行を含むファイルがあります。
.......... FROM ABCD_EXT
.......... FROM HEG_EXT1
.......... from
xyz_EXT
.......... FROM abd_EXT2
..........where QWT_EXT.SID=POI_EXT.GET
..........where QWT_EXT.SID=POI_GET.END_EXT
「FROM」(大文字と小文字を区別しない)の横または下にあり、_EXTで終わる単語をgrepします。
つまり、予想される出力は次のようになります。
ABCD_EXT
xyz_EXT
編集:はい、同じ行に表示されるか、次の行に表示されるか、「from」の後の次の単語をgrepする必要があります。
私はこれを試して最初の部分を正しく得ました(同じ行)。
grep _EXT rt.sql |grep -i from|sed -e 's/_EXT/_EXT /g'|awk '{print $NF}'|grep _EXT
下の行から単語を取得するのは問題です。
答え1
そしてpcregrep
:
pcregrep -Mo1 '(?<!\S)(?i:from)\s+(\S*_EXT)(?!\S)' < rt.sql
-M
M
複数行モードの場合-o1
最初のキャプチャo
グループと一致するコンテンツを出力します。1
\s
スペース文字(少なくともスペース、タブ、CR、およびLFを含む)と一致し、スペース以外の\S
文字と一致します。x+
:1つ以上のx
sと一致x*
:0個以上のx
sと一致します。(?i:from)
:from
、、大文字と小文字を区別せず、と同じです[fF][rR][oO][mM]
。(?<!\S)
: 空白でない場合、またはIOWの否定的な振り返り前提は、前の内容が空ではないということです。(スペースやトピックの先頭にも同じことが当てはまります)。(?!\S)
:同じですが、後ろではなく前を見てください。 SQLなら、;
許可したいかもしれません。(?![^\s;])
そのエントリがない場合は、pcregrep
(の最初のエントリperl
)を使用してファイル全体を延期できます。p
pcregrep
-0777
perl -l -0777 -ne 'print for /(?<!\S)(?i:from)\s+(\S*EXT)(?!\S)/g' < rt.sql
あるいは、GNUを使用してgrep
PCREサポートで構築されている場合(これは-P
Perlなどの正規表現を一致させるためのオプションを追加します):
grep -zPo '(?<!\S)(?i:from)\s+\K\S*EXT(?!\S)' < rt.sql | tr '\0' '\n'
GNUは最初のキャプチャグループ一致の印刷をgrep
サポートしていないため、代わりに一致の内容全体を印刷しますが、一致で何をeepするかをマッチャーに伝えます。-o<n>
n
-o
\K
K
行ではなく NUL で区切られたレコードを処理するため、-z
入力に NUL が含まれていないと仮定すると (通常は SQL とテキストの場合に該当する)、これはファイルの全内容を構成する 1 つのレコードになります。 Perlのように上記のフルルックパターン。ただし、出力レコード区切り文字もNULなので、tr
各一致が別々の行になるように改行に変換する必要があります。
答え2
GNUの使用sed
$ sed -En 'N;s/.*from( ([^_]*_ext\>)[^\n]*\n.*|\n.* ([[:alpha:]]+_ext\>))/\2\3/Ip' input_file
ABCD_EXT
xyz_EXT
答え3
サンプルデータで試してくださいdatafile
。
> awk -v printfirst=0 'BEGIN {IGNORECASE=1}
{if (printfirst == 1) {
print $1; printfirst=0; next
}
}
{for (i=1;i<=NF;i++)
if ($i ~ /^from$/) {
if (i == NF) {printfirst=1}
else if ($(i+1) ~ /_EXT$/) {print $(i+1)}
}
}' datafile
ABCD_EXT
xyz_EXT
> _
これを行う方法はいくつかありますawk
(ここではAwkのGNUバージョンがあります)。私は便宜上、入力ファイルを2回解析するのを避けるためにこれを選択しました。
-v
Awkに変数を渡すためのフラグです。変数をprintfirst
ゼロに初期化し、BEGIN {IGNORECASE=1}
Awk検索パターンで大文字と小文字を区別しないように設定する- 最初の
{}
ブロック:最初のAwkフィールドを条件付きで印刷します。つまり、レコード$1
にジャンプします。next
- 2番目のブロック
{}
:解析されたレコードfrom
の場合、大文字と小文字を区別せずに各フィールドを一致させようとします。- 一致するものがなければ、何もしません。
- 一致する場合:
- 一致するフィールドがレコードの最後のフィールドである場合は、awk内部変数を
printfirst
1に設定して次のレコードに移動します。 - 一致するフィールドがレコードの最後のフィールドでない場合は、レコードの次のフィールドを印刷します。
- 一致するフィールドがレコードの最後のフィールドである場合は、awk内部変数を