![查找并提取直接字符](https://linux22.com/image/131583/%E6%9F%A5%E6%89%BE%E5%B9%B6%E6%8F%90%E5%8F%96%E7%9B%B4%E6%8E%A5%E5%AD%97%E7%AC%A6.png)
我有一个包含一些 SQL 的文件,我想找出使用 shell 脚本进行转换的字段。
例如,我有一个文件 abc.txt ,其中包含以下 sql
SELECT field1,field2,field3,field4,cast(field5 作为整数),cast(substr(field6,5,10) 作为整数),(当 field7 = '0000/00/00' 时则cast(field7 作为日期) else (field8 作为日期) end) as field7, substr(field9,5,10) FROM TEMP;
期望的输出:
字段5
字段6
字段7
答案1
怎么样:
awk 'BEGIN{FS="cast\\(";OFS="\n\n"}{ for(i = 1; i <= NF; i++) { sub("[ ),].*","",$i);gsub("^.*\\(","",$i) } {$1=""; print}}'
该解决方案迭代任何行上的“cast(”实例,然后去掉前缀和后缀。
答案2
field<decimals>
要在语句内查找出现的情况cast(...)
,假设没有不匹配的括号,并且使用 GNUgrep
或与 PCRE 支持构建的兼容:
<abc.txt grep -Po 'cast(\((?:[^()]++|(?1))*\))' |
grep -Po '\bfield\d+\b'
这是利用 PCRE 的能力来定义递归的常用表达。上面引用(?1)
的是包含在 中的正则表达式(...)
,因此我们正在寻找后面cast
跟着一个以 开头的正则表达式“R”,(
后跟任意数量的非括号(++
只是 的非回溯版本+
)或更多“R”其次是)
。
这使我们能够找到接下来的)
空缺的匹配。(
cast
第二个grep
仅提取field<decimal>
(周围是单词边界( \b
)) 来自cast(...)
第一个grep
提取的语句。
假设这些 SQL 语句位于一行上。如果没有,您可以将该-z
选项添加到第一个grep
.