我有由 3 行组成的段落,我需要将行上方和下方的单词与名称相匹配。
当前文件
time toto
time toto name titi
time toto
time tutu
time tutu name tata
time tutu
我想要这个。
time titi
time titi name titi
time titi
time tata
time tata name tata
time tata
我已经尝试过但没有成功。
awk 'NR>1{if(/name/) sub($2,$4,prev); print prev} {prev=$0}' fic.txt
你有解决方案吗 ?
答案1
如果您的输入确实如您所显示的那样,并且所有受影响的字符串不包含正则表达式元字符或反向引用,并且不会在您的输入中显示为子字符串或任何其他不需要的地方,那么:
$ awk -v RS= -v ORS='\n\n' '{gsub($2,$6)}1' file
time titi
time titi name titi
time titi
time tata
time tata name tata
time tata
如果这不是您所需要的全部,那么编辑您的问题以提供更真正具有代表性的示例输入/输出,其中包括这不起作用的情况。
答案2
当您的脚本找到匹配的行时,它仅修改前一行/name/
。您还必须修改当前行和下一行。
该脚本将执行请求的修改:
awk '$3=="name" { search=$2; repl=$4; } # define new replacement
NR>1 {
sub(search,repl,prev); print prev; # modify and print previous line
}
{
prev=$0; # save line for next processing cycle
}
END {
sub(search,repl,prev); print prev; # process last line
}' fic.txt
当然你可以删除评论。
使用它打印的示例输入文件:
time titi
time titi name titi
time titi
time tata
time tata name tata
time tata
另一个版本依赖于前提条件,即字段数量与示例输入中所示完全相同,并且在每个组中,第一行和第三行可以从第二行派生:
awk 'NF>2 {
print $1,$4;
print $1, $4, $3, $4;
print $1, $4;
print "";
}' fic.txt
答案3
其他方式 :
awk '{
if ( NF==2 ) {
pr=$0
}
if ( NF>2 ) {
split(pr,a) ; print a[1]FS$4
sub($2,$4) ; print
split(pr,a) ; print a[1]FS$4
}
if ( NF==0 ) { print }
}' fic.txt