我有一个文件,其中 i 包含以下几行:
.......... 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
我只需要 grep 那些位于“FROM”(不区分大小写)旁边或下方且以 _EXT 结尾的单词。
即,预期输出是:
ABCD_EXT
xyz_EXT
编辑:是的,我需要 grep 'from' 之后的下一个单词,无论它出现在同一行还是下一行。
我尝试了这个,它让我正确地得到了第一部分(同一行):
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
输出sto
捕获组匹配的内容。1
\s
匹配空白字符(至少包括空格、制表符、CR 和 LF),\S
匹配非空白字符。x+
: 匹配 1 个或多个x
sx*
: 匹配 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'
由于 GNUgrep
不支持-o<n>
输出n
第一个捕获组匹配的内容,因此我们改为-o
输出匹配的全部内容,但用于\K
告诉匹配器要K
eep 的内容作为匹配。
由于-z
我们处理的是 NUL 分隔的记录而不是行,因此假设输入不包含 NUL(通常 SQL 和文本应该是这种情况),那么这将只是一个记录,构成文件的完整内容,就像在 perl 中一样上面的 slurp 模式。不过,输出记录分隔符也将为 NUL,因此我们需要将tr
它们转译为换行符,以使每个匹配项位于单独的行上。
答案2
使用GNUsed
$ 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 版本)来执行此操作。我选择这个是为了方便,避免两次解析输入文件。
-v
将变量传递到 Awk 的标志。初始化变量printfirst
为0,BEGIN {IGNORECASE=1}
使 Awk 搜索模式不区分大小写- 第一个
{}
块:有条件地打印第一个 Awk 字段,即$1
并跳转到next
记录 - 第二块
{}
:对于解析的记录,尝试以from
不区分大小写的方式匹配每个字段。- 如果不匹配:什么也不做。
- 如果匹配:
- 如果匹配字段是记录中的最后一个,则将 awk 内部变量设置
printfirst
为 1 并转到下一条记录 - 如果匹配的字段不是记录中的最后一个字段,则打印记录中的下一个字段。
- 如果匹配字段是记录中的最后一个,则将 awk 内部变量设置