sql - AWK FPAT 无法按预期进行字符串解析
问题描述
我必须解析一个非常长的字符串(来自标准输入)。它基本上是一个 .sql 文件。我必须从中获取数据。我正在努力解析数据,以便可以将其转换为 csv。为此,我正在使用 awk。就我而言,一个示例片段(两条记录)如下:
b="(abc@xyz.com,www.example.com,'field2,(2)'),(dfr@xyz.com,www.example.com,'field0'),"
echo $b|awk 'BEGIN {FPAT = "([^\\)]+)|('\''[^'\'']+'\'')"}{print $1}'
在我的正则表达式中,我说的是“)”括号上的拆分,或者如果找到单引号,则忽略所有文本,直到找到最后一个引号。但我的输出如下:
(abc@xyz.com,www.example.com,'field2,(2
我期待这个输出
(abc@xyz.com,www.example.com,'field2,(2)'
我的代码中的问题在哪里。我搜索了很多并检查了 awk 手册,但没有成功。
解决方案
我在下面的第一个答案是错误的,您正在尝试做的事情有一个 ERE:
$ echo "$b" | awk -v FPAT="[(]([^)]|'[^']*')*)" '{for (i=1; i<=NF; i++) print $i}'
(abc@xyz.com,www.example.com,'field2,(2)')
(dfr@xyz.com,www.example.com,'field0')
原始答案,另一种方法:
您需要一种 2-pass 方法,首先将)
引用字段中的所有 s 替换为输入中尚不存在的内容(例如 RS),然后识别(...)
字段并将 RS 放回)
s 之前打印它们:
$ echo "$b" |
awk -F"'" -v OFS= '
{
for (i=2; i<=NF; i+=2) {
gsub(/)/,RS,$i)
$i = FS $i FS
}
FPAT = "[(][^)]*)"
$0 = $0
for (i=1; i<=NF; i++) {
gsub(RS,")",$i)
print $i
}
FS = FS
}
'
(abc@xyz.com,www.example.com,'field2,(2)')
(dfr@xyz.com,www.example.com,'field0')
由于 FPAT(或者我们可以使用 gawk patsplit()
),上述内容仅适用于 gawk,而其他 awk 则使用了 while-match()-substr() 循环:
$ echo "$b" |
awk -F"'" -v OFS= '
{
for (i=2; i<=NF; i+=2) {
gsub(/)/,RS,$i)
$i = FS $i FS
}
while ( match($0,/[(][^)]*)/) ) {
field = substr($0,RSTART,RLENGTH)
gsub(RS,")",field)
print field
$0 = substr($0,RSTART+RLENGTH)
}
}
'
(abc@xyz.com,www.example.com,'field2,(2)')
(dfr@xyz.com,www.example.com,'field0')
推荐阅读
- c++ - 终端不会运行新编译的文件,总是运行之前编译的文件
- r - 计算平均帧速率的正确方法是什么?
- php - 如何从自定义 WooCommerce 支付网关设置自定义结帐支付字段
- html - 即使他们在同一个目录中,Html也不会加载图像
- python - Python 代码中的错误(从数学导入 - PI)
- ruby - 为什么一种回溯方法比另一种更快?
- javascript - AppleScript 无法点击输入标签来添加文件
- excel - 有没有办法在 Workbook.Open 中动态更改或指定 excel 文件的位置?
- java - Selenium Webdriver:如何绕过 Google 的“接受 cookie”对话框
- c - 为什么当我使用 switch 语句时我的变量没有更新?