使用 awk 或 sed 连接具有模式的行

使用 awk 或 sed 连接具有模式的行

我本质上想将查询的名称放在包含 SourceField 的每一行的前面。

我尝试过这个串联方案

awk '/<\^Query/ && p{print p;p=""}{p=p $0}END{if(p) print p}' 

但这只有在我有多个源字段时才有效。当发生这种情况时,它将所有行与 SourceField 连接起来:

Query: D Monthly Loan SourceField: LOAD-NO         SourceTable: MASTER SourceField: LO  

我的数据是:

Query: D Monthly Loan
    SourceField: LOAD-NO         SourceTable: MASTER
    SourceField: LO              SourceTable: MASTER
Query: D Monthly Loan
    SourceField: HI              SourceTable: MASTER2
QUERY: M FORBEARANCE_1
    SourceField: LOAN-NO         SourceTable: MASTER

我希望输出看起来像这样:

Query: D Monthly Loan SourceField: LOAD-NO         SourceTable: MASTER
Query: D Monthly Loan SourceField: LO              SourceTable: MASTER
Query: D Monthly Loan SourceField: HI              SourceTable: MASTER2
Query: M FORBEARANCE_1 SourceField: LOAN-NO        SourceTable: MASTER

答案1

$ awk '/^ +/{print q, $0; next} {q=$0}' file
Query: D Monthly Loan     SourceField: LOAD-NO         SourceTable: MASTER
Query: D Monthly Loan     SourceField: LO              SourceTable: MASTER
Query: D Monthly Loan     SourceField: HI              SourceTable: MASTER2
QUERY: M FORBEARANCE_1     SourceField: LOAN-NO         SourceTable: MASTER

或者如果您更喜欢这些格式中的任何一种(还有许多其他可能性!):

$ awk 'sub(/^ +/,""){print q, $0; next} {q=$0}' file
Query: D Monthly Loan SourceField: LOAD-NO         SourceTable: MASTER
Query: D Monthly Loan SourceField: LO              SourceTable: MASTER
Query: D Monthly Loan SourceField: HI              SourceTable: MASTER2
QUERY: M FORBEARANCE_1 SourceField: LOAN-NO         SourceTable: MASTER

$ awk '/^ +/{$1=$1; print q, $0; next} {q=$0}' file
Query: D Monthly Loan SourceField: LOAD-NO SourceTable: MASTER
Query: D Monthly Loan SourceField: LO SourceTable: MASTER
Query: D Monthly Loan SourceField: HI SourceTable: MASTER2
QUERY: M FORBEARANCE_1 SourceField: LOAN-NO SourceTable: MASTER

$ awk -v OFS='\t' '/^ +/{$1=$1; print q, $0; next} {q=$0}' file
Query: D Monthly Loan   SourceField:    LOAD-NO SourceTable:    MASTER
Query: D Monthly Loan   SourceField:    LO      SourceTable:    MASTER
Query: D Monthly Loan   SourceField:    HI      SourceTable:    MASTER2
QUERY: M FORBEARANCE_1  SourceField:    LOAN-NO SourceTable:    MASTER

答案2

sed -n -e '/^Query:\|^QUERY:/{h;}' -e '/^  *SourceField:/{G;s|\(.*\)\n\(.*\)|\2\1|p;}' file
  • /^Query:\|^QUERY:/{h;}如果行以Query:/开头QUERY:,则将其放入保留空间。
  • / *SourceField:/如果行以任意数量的空格开头,后跟SourceField:,则:
    • G在其前面附加一个换行符的保留空间的内容。
    • s|\(.*\)\n\(.*\)|\2\1|p交换换行符周围的字段并打印结果。

简化版本,如果您的 sed 支持扩展正则表达式:

sed -nE -e '/^Query:|^QUERY:/{h;}' -e '/^ +SourceField:/{G;s|(.*)\n(.*)|\2\1|p;}' file

输出:

Query: D Monthly Loan    SourceField: LOAD-NO         SourceTable: MASTER
Query: D Monthly Loan    SourceField: LO              SourceTable: MASTER
Query: D Monthly Loan    SourceField: HI              SourceTable: MASTER2
QUERY: M FORBEARANCE_1    SourceField: LOAN-NO         SourceTable: MASTER

答案3

使用 GNU awk:

awk '/^Q/{query=$0; next}; /^ /{gsub(/^ */,"",$0); print query,$0}' file

输出:

查询:D 每月贷款 源字段:LOAD-NO 源表:MASTER
查询:D 每月贷款 来源字段:LO 来源表:MASTER
查询:D 每月贷款 来源字段:HI 来源表:MASTER2
查询:M FORBEARANCE_1 源字段:贷款-否 源表:MASTER

gsub(/^ */,"",$0)删除前导空格。

答案4

awk '
/^Query:/ || /^QUERY:/ {queryline=$0}
/ SourceField:/ {print queryline " " $0}
' data.txt

相关内容