我正在尝试使用awk
从多行中提取不同的详细信息。
但是,我无法运行测试,并将结果输出打印在一行中。
信息位于不同的块中,然后我需要提取块内的详细信息..
awk '
TRA TRB TRC
/EKYC/{for(i=1; i<10; i++)
{ (getline p )
if ( match(p,"TRA")) { print substr(p,4)}
if ( match(p,"TRB")) { print substr(p,4)}
if ( match(p,"TRC")) { print substr(p,4)}
}
}
' inputfile
EKYC块将在那里,代码TRA TRB TRC将位于EKYC块之间。
示例文本文件如下所示::
EKYC
TRA onlyThisTRA1
TRB onlyThisTRB1
THR notThis
EKYC
TRA onlyThisTRA2
TRB onlyThisTRB2
TRC onlyThisTRC2
EKYC
NOT
TRA onlyThisTRA3
YEH not this
TRC onlyThisTRC3
所需的输出..每块一行
onlyThisTRA1 onlyThisTRA2 null
onlyThisTRA2 onlyThisTRB2 onlyThisTRC2
onlyThisTRA3 null onlyThisTRC3
答案 0 :(得分:1)
您可以使用此awk
命令:
awk '/EKYC/{if (tra != "null") print tra, trb, trc; tra=trb=trc="null"; next}
$1=="TRA"{tra=$2} $1=="TRB"{trb=$2} $1=="TRC"{trc=$2}
END{print tra, trb, trc}' file
onlyThisTRA1 onlyThisTRB1 null
onlyThisTRA2 onlyThisTRB2 onlyThisTRC2
onlyThisTRA3 null onlyThisTRC3
答案 1 :(得分:1)
使用awk多维数组:
n
当看到EKYC时设置增量cnt并重新初始化cnt1。使用计数器创建存储第二个空间数据的数据和数组。最后循环遍历多维数组以打印数据。
答案 2 :(得分:1)
awk 解决方案:
awk 'function pr(a){
n="null"; tra=a["TRA"]; trb=a["TRB"]; trc=a["TRC"];
printf "%s %s %s\n",(tra)? tra:n,(trb)? trb:n,(trc)? trc:n; delete a
}
/EKYC/{ if(f){ pr(a); f=0 } }
/^TR[ABC]/{ a[$1]=$2; f=1 }END{ pr(a) }' file
输出:
onlyThisTRA1 onlyThisTRB1 null
onlyThisTRA2 onlyThisTRB2 onlyThisTRC2
onlyThisTRA3 null onlyThisTRC3
答案 3 :(得分:1)
每当您拥有数据中的名称 - 值对时,最好的方法是首先创建一个捕获该映射的数组(下面为n2v[]
),然后您可以按名称引用这些值:
$ cat tst.awk
BEGIN { OFS="\t" }
/EKYC/ { prt(); next }
{ n2v[$1] = $2 }
END { prt() }
function prt() { if (length(n2v)) print v("TRA"), v("TRB"), v("TRC"); delete n2v }
function v(n) { return (n in n2v ? n2v[n] : "null") }
$ awk -f tst.awk file
onlyThisTRA1 onlyThisTRB1 null
onlyThisTRA2 onlyThisTRB2 onlyThisTRC2
onlyThisTRA3 null onlyThisTRC3
请注意,上面提到的每个名称在大写或小写中都只显示一次,并且没有基于数据中的值命名的变量,因此如果您需要添加新名称,则需要得到打印(例如“THC”)然后你只需在prt()函数中添加, v("THC")
,它只在一个地方指定默认的null
值,所以如果你想要一个不同的默认值或不同的算法要确定默认值,您只需更改v()
函数。
修改脚本以接受要在命令行上打印的名称列表实际上是微不足道的:
$ cat tst.awk
BEGIN { OFS="\t" }
/EKYC/ { prt(); next }
{ val=$0; sub(/^[^[:space:]]+[[:space:]]+/,"",val); n2v[$1] = val }
END { prt() }
function prt( nameList,nameNr,numNames) {
if (length(n2v)) {
numNames = split(names,nameList)
for (nameNr=1; nameNr <= numNames; nameNr++) {
printf "%s%s", v(nameList[nameNr]), (nameNr<numNames ? OFS : ORS)
}
delete n2v
}
}
function v(n) { return (n in n2v ? n2v[n] : "null") }
$ awk -v names='TRA TRB TRC' -f tst.awk file
onlyThisTRA1 onlyThisTRB1 null
onlyThisTRA2 onlyThisTRB2 onlyThisTRC2
onlyThisTRA3 null onlyThisTRC3
$ awk -v names='TRA THR TRC YEH' -f tst.awk file
onlyThisTRA1 notThis null null
onlyThisTRA2 null onlyThisTRC2 null
onlyThisTRA3 null onlyThisTRC3 not this
请注意,我修改了在第二个脚本中填充n2v[]
的方式,以允许在您的名称值之后出现空格,因为您的YEH
值(我现在在上面打印)有一个空间。如果没有空格,则不需要进行更改,如果分隔符是制表符,则只需在BEGIN部分设置FS="\t"
,然后再不需要修改。