我有一个这样的文件:
419 I 0.3529
420 S 0.3182
421 T 0.3740
422 Y 0.3872
423 I 0.3460
424 E 0.4409
425 S 0.3182
426 T 0.3740
427 Y 0.4141
428 I 0.3460
429 S 0.3131
430 Y 0.3838
431 T 0.3939
432 S 0.3101
我正在尝试制作一个Awk程序来评估大于或等于0.4的数字的第三列。如果为true,则在该字母中向上取4个字符,向下取4个字符(第二列)。如果有多个匹配,我想为每个匹配一个固定长度的字符串:
STYIESTYI
IESTYISYT
第一个是因为编号为424的线上有匹配;第二个是编号为427的行的(部分重叠)匹配。我将如何处理?
答案 0 :(得分:4)
$ cat tst.awk
BEGIN {
tgt = (tgt=="" ? 0.4 : tgt)
cxt = (cxt=="" ? 4 : cxt)
bef = (bef=="" ? cxt : bef)
aft = (aft=="" ? cxt : aft)
}
$3 >= tgt { hits[++numHits] = NR }
{ chars[NR] = $2 }
END {
for (hitNr=1; hitNr<=numHits; hitNr++) {
for (lineNr=(hits[hitNr]-bef); lineNr<=(hits[hitNr]+aft); lineNr++) {
printf "%s", (lineNr in chars ? chars[lineNr] : "")
}
print ""
}
}
$ awk -f tst.awk file
STYIESTYI
IESTYISYT
请注意,如果第3个字段&gt; = 0.4的行比文件的开头和/或结尾的4行更接近,这将表现得很明智 - 请确保测试那些具有任何潜在答案的条件,因为它们是常见的对于这类问题的雨天案例,提供潜在解决方案的人往往忘记报道。
例如,尝试使用此输入文件的所有潜在解决方案,看看是否得到了您期望的输出:
$ cat file1
421 T 0.3740
422 Y 0.3872
423 I 0.3460
424 E 0.4409
425 S 0.3182
426 T 0.3740
427 Y 0.4141
428 I 0.3460
429 S 0.3131
430 Y 0.3838
$ awk -f tst.awk file1
TYIESTYI
IESTYISY
或者如果您丢失输出行或带有前导/尾随空格或其他不良字符或其他内容的行。
另请注意,您可以将目标值从0.4更改为其他值,并且可以通过设置命令行参数来更改要在匹配行之前和/或之后打印的数字上下文行,例如
在0.37之前和之后打印5行上下文:
$ awk -v tgt=0.37 -v cxt=5 -f tst.awk file
ISTYIEST
ISTYIESTY
ISTYIESTYIS
TYIESTYISYT
YIESTYISYTS
STYISYTS
TYISYTS
打印前一行和0.34后的两行:
$ awk -v tgt=0.34 -v bef=1 -v aft=2 -f tst.awk file
IST
STYI
TYIE
YIES
IEST
STYI
TYIS
YISY
SYTS
YTS
答案 1 :(得分:3)
myDict = {'a': # This is fine
'b'} # fine
myDict = {'ä': # fine
'b'} # fine
myTuple = ('a', # fine
'b') # fine
myTuple = ('ä', # fine
'b') # fine
myC = ('a', {'b': 'c', # fine
'd': 'e'}) # fine
myC = ('ä', {'b': 'c', # fine
'd': 'e'}) # E128: continuation line under-indented[...]
救援!
awk
如果您的文件很大,滚动窗口可能是更好的解决方案。
更新:根据@Ed Morton的评论,脚本总是希望匹配后会有4条尾随线。如果不是这样,则需要添加特殊的END块来处理悬空线。
$ awk '{a[NR]=$2; v[NR]=$3>0.4}
v[NR-4]{for(i=NR-8;i<=NR;i++)
printf "%s", a[i];
print ""}' file
STYIESTYI
IESTYISYT
答案 2 :(得分:1)
num
以计算接下来的四个字符。请注意使用printf
而不是print
来避免自动换行。
// {if ($3 > 0.4) {printf "%s", v0 v1 v2 v3 ;
v0 = v1 = v2 = v3 = "";
num = 4}
if (num > 0) {
printf "%s", $2;
num = num -1;
} else { v0 = v1; v1 = v2; v2 = v3; v3 = $2; }
}