original data and desired output
你好
我想在模式之间获取特定的变量值并在其前面打印( REF_ID 值, C_ID 值和日期时间)。 / p>
您可以在下面看到原始数据和所需的输出:
输入:
[2018 13:50] ALI
REF_ID X
A 3
C_ID Y
B 4
[2018 14:00] ALI
C 3
REF_ID Z
D 1
E 4
C_ID T
所需的输出:
[2018 13:50] X Y [2018 13:50] ALI
[2018 13:50] X Y REF_ID X
[2018 13:50] X Y A 3
[2018 13:50] X Y C_ID Y
[2018 13:50] X Y B 4
[2018 14:00] Z T [2018 14:00] ALI
[2018 14:00] Z T C 3
[2018 14:00] Z T REF_ID Z
[2018 14:00] Z T D 1
[2018 14:00] Z T E 4
[2018 14:00] Z T C_ID T
我尝试了以下操作,但无法按我的要求工作。
awk '
BEGIN {FS=" "}
{if ($0 ~ /\[2018/) {flag=1;date_ref=$1;time_ref=$2;} }
{if ($0 ~ /REF_ID/ ) {t_ref=$2} }
{if ($0 ~ /C_ID/ ) {gcid_ref=$2} }
{if (flag=1) print date_ref,time_ref,t_ref,gcid_ref,$0}
'
我得到的输出:
[2018 13:50] [2018 13:50] ALI
[2018 13:50] X REF_ID X
[2018 13:50] X A 3
[2018 13:50] X Y C_ID Y
[2018 13:50] X Y B 4
[2018 14:00] X Y [2018 14:00] ALI
[2018 14:00] X Y C 3
[2018 14:00] Z Y REF_ID Z
[2018 14:00] Z Y D 1
[2018 14:00] Z Y E 4
[2018 14:00] Z T C_ID T
要解决这个问题,我相信必须将数据放入缓冲区,收集变量并将其合并。
能帮我解决这个问题吗?如果您可以解释所提供的代码,将会很有帮助。
答案 0 :(得分:1)
我相信您可能对此感兴趣:
awk '($1 ~ /^\[/) && record {
string= date_ref OFS time_ref OFS t_ref OFS gcid_ref OFS
gsub(ORS,ORS string, record)
print string record
record=""
}
($1 ~ /^\[/) { date_ref=$1; time_ref=$2 }
($1 == "REF_ID") { t_ref=$2 }
($1 == "C_ID") { gcid_ref=$2 }
{ record = record ? record ORS $0 : $0 }
END { string= date_ref OFS time_ref OFS t_ref OFS gcid_ref OFS
gsub(ORS,ORS string, record)
print string record
}' <file>
输出:
[2018 13:50] X Y [2018 13:50] ALI
[2018 13:50] X Y REF_ID X
[2018 13:50] X Y A 3
[2018 13:50] X Y C_ID Y
[2018 13:50] X Y B 4
[2018 14:00] Z T [2018 14:00] ALI
[2018 14:00] Z T C 3
[2018 14:00] Z T REF_ID Z
[2018 14:00] Z T D 1
[2018 14:00] Z T E 4
[2018 14:00] Z T C_ID T
以上代码的想法是在打印任何内容之前将record
内置到内存中。在建立记录时,您会选择相关信息,例如date_ref
time_ref
,t_ref
和gcid_ref
($1 ~ /^\[/) && record
记录开始时(以[
开头的行表示),您必须根据选择的信息对上一条记录执行操作。 (除非它为空)
string= date_ref OFS time_ref OFS t_ref OFS gcid_ref OFS
:构建要放置在每行之前的string
(OFS
默认为空格)gsub(ORS,ORS string, record)
用ORS
替换所有换行符(默认值ORS string
)print string record
::打印记录,记录前面有字符串
作为第一行,它前面没有字符串。record=""
重设record
,因为从现在开始建立新记录。 ($1 ~ /^\[/) { ... }
,($1 == "REF_ID"){...}
和($1 == "C_ID") { }
:在满足正确条件(即第一个字段等于或匹配适当的事物)时提取相关信息。
{ record = record ? record ORS $0 : $0 }
通过在当前行后面添加换行符来构建记录(ORS
默认为换行符)。请注意,您必须检查记录是否为空,以便开头没有多余的ORS
。
END
,您仍然需要打印最后一条记录。再次执行步骤1中的所有操作。
答案 1 :(得分:1)
$ cat tst.awk
/^\[/ {
prt()
time = $1 FS $2
}
{
map[$1] = $2 # save every 1st field to 2nd field mapping,
# e.g. map["REF_ID"]="X", map["C_ID"]="Y", etc.
rec[++numLines] = $0
}
END { prt() }
function prt( lineNr) {
for (lineNr=1; lineNr<=numLines; lineNr++) {
# now just retrieve the 2nd field values by their 1st field names
print time, map["REF_ID"], map["C_ID"], rec[lineNr]
}
numLines = 0
}
$ awk -f tst.awk file
[2018 13:50] X Y [2018 13:50] ALI
[2018 13:50] X Y REF_ID X
[2018 13:50] X Y A 3
[2018 13:50] X Y C_ID Y
[2018 13:50] X Y B 4
[2018 14:00] Z T [2018 14:00] ALI
[2018 14:00] Z T C 3
[2018 14:00] Z T REF_ID Z
[2018 14:00] Z T D 1
[2018 14:00] Z T E 4
[2018 14:00] Z T C_ID T