Bash AWK将空列值替换为上一行的列值

Bash AWK将空列值替换为上一行的列值,bash,awk,replace,Bash,Awk,Replace,我有一个示例文件,如下所示: cat sample.txt HOST dev@opulex.com PORT 1066 DATABASE ORACLE_1 SCHEMA DEPT.*; SCHEMA EMP.*; DATABASE ORACLE_2 SCHEMA JOB.*; cat sample.txt | awk 'tolower($0)~/^host|^port|^database|^schema/{printf "%s",$2 OFS;}' | awk -v RS=';' -v OR

我有一个示例文件,如下所示:

cat sample.txt

HOST dev@opulex.com
PORT 1066
DATABASE ORACLE_1
SCHEMA DEPT.*;
SCHEMA EMP.*;
DATABASE ORACLE_2
SCHEMA JOB.*;
cat sample.txt | awk 'tolower($0)~/^host|^port|^database|^schema/{printf "%s",$2 OFS;}' | awk -v RS=';' -v ORS=';\n' 'NF'

dev@opulex.com 1066 ORACLE_1 DEPT.*;
 EMP.*;
 ORACLE_2 JOB.*;
 dev@opulex.com 1066 ORACLE_1 DEPT.*;
 dev@opulex.com 1066 ORACLE_1 EMP.*;
 dev@opulex.com 1066 ORACLE_2 JOB.*;
对于上面示例文件中的内容,我只想打印HOST/PORT/DATABASE/SCHEMA旁边的列。因此,我可以实现以下目标:

cat sample.txt

HOST dev@opulex.com
PORT 1066
DATABASE ORACLE_1
SCHEMA DEPT.*;
SCHEMA EMP.*;
DATABASE ORACLE_2
SCHEMA JOB.*;
cat sample.txt | awk 'tolower($0)~/^host|^port|^database|^schema/{printf "%s",$2 OFS;}' | awk -v RS=';' -v ORS=';\n' 'NF'

dev@opulex.com 1066 ORACLE_1 DEPT.*;
 EMP.*;
 ORACLE_2 JOB.*;
 dev@opulex.com 1066 ORACLE_1 DEPT.*;
 dev@opulex.com 1066 ORACLE_1 EMP.*;
 dev@opulex.com 1066 ORACLE_2 JOB.*;
假设每条记录中的最后一列以分号结尾,我如何使用AWK将空列值替换为前一行的列值,如下所示:

cat sample.txt

HOST dev@opulex.com
PORT 1066
DATABASE ORACLE_1
SCHEMA DEPT.*;
SCHEMA EMP.*;
DATABASE ORACLE_2
SCHEMA JOB.*;
cat sample.txt | awk 'tolower($0)~/^host|^port|^database|^schema/{printf "%s",$2 OFS;}' | awk -v RS=';' -v ORS=';\n' 'NF'

dev@opulex.com 1066 ORACLE_1 DEPT.*;
 EMP.*;
 ORACLE_2 JOB.*;
 dev@opulex.com 1066 ORACLE_1 DEPT.*;
 dev@opulex.com 1066 ORACLE_1 EMP.*;
 dev@opulex.com 1066 ORACLE_2 JOB.*;
提前谢谢

如果您有此数据:

cat file

dev@opulex.com 1066 ORACLE_1 DEPT.*;
 EMP.*;
 ORACLE_2 JOB.*;
使用awk,您可以执行以下操作:

awk 'NF==1{print c1, c2, c3, $1; next}
     NF==2{print c1, c2, $1, $2; next}
     {c1=$1; c2=$2; c3=$3} 1' file
输出:

dev@opulex.com 1066 ORACLE_1 DEPT.*;
dev@opulex.com 1066 ORACLE_1 EMP.*;
dev@opulex.com 1066 ORACLE_2 JOB.*;

另一种
awk
替代方案

$ rev file | 
  awk 'NF>1{c2=$2?$2:c2; c3=$3?$3:c3; c4=$4?$4:c4}
           {print $1,c2,c3,c4}' | 
  rev

dev@opulex.com 1066 ORACLE_1 DEPT.*;
dev@opulex.com 1066 ORACLE_1 EMP.*;
dev@opulex.com 1066 ORACLE_2 JOB.*;

谢谢你的回复。您能详细说明一下逻辑吗?当只有一个单元格值
NF==1
时,我们使用先前保存在
c1、c2、c3
变量中的值。当有两个单元格值
NF==2
时,我们使用先前保存在
c1、c2
变量中的值。最后,当所有列都可用时,我们将列值保存在
c1、c2、c3
变量中(稍后使用)。感谢您的解释。
$>cat sample2.txt HOSTdev@opulex.com端口1066数据库ORACLE_1模式部门*;模式EMP.*;数据库ORACLE_2模式作业。*;模式工资*
$>cat sample2.txt | awk'tolower($0)~/^host | ^port | ^database | ^schema/{printf“%s”,$2 of s;}| awk-v RS=''-v ORS='\n''NF'| awk'NF==1{print c1,c2,c3,$1;next}NF==2{print c1,c2,$1,$2;next}{c1=$1;c2=$2;c3=$3}1'| sed's | ^[:blank:]*.| g;s| \$||g'>dev@opulex.com1066 ORACLE_1部门*dev@opulex.com1066 ORACLE_1 EMP.*dev@opulex.com1066 ORACLE_2作业。*dev@opulex.com1066 ORACLE_1薪水。*
很抱歉@anubhava。。我在这里创建了一个新问题,而这段代码可能会回答这个问题,提供关于为什么和/或如何回答这个问题的额外上下文将显著提高其长期价值。请在您的回答中添加一些解释。