【问题标题】:Awk printing specific variable & original data together between the patternawk 在模式之间一起打印特定变量和原始数据
【发布时间】:2018-09-25 12:38:27
【问题描述】:

original data and desired output

你好,

我想获取 Patterns 和 print 之间的特定变量值( REF_ID 值、C_ID 值和它前面的 Date-Time

您可以在下面看到原始数据和所需输出:

输入:

[2018 13:50] ALI
REF_ID X 
A 3 
C_ID Y 
B 4 
[2018 14:00] ALI
C 3 
REF_ID Z 
D 1 
E 4 
C_ID T 

需要输出:

[2018 13:50] X Y [2018 13:50] ALI
[2018 13:50] X Y REF_ID X 
[2018 13:50] X Y A 3 
[2018 13:50] X Y C_ID Y 
[2018 13:50] X Y B 4 
[2018 14:00] Z T [2018 14:00] ALI
[2018 14:00] Z T C 3 
[2018 14:00] Z T REF_ID Z 
[2018 14:00] Z T D 1 
[2018 14:00] Z T E 4 
[2018 14:00] Z T C_ID T 

我已经尝试了以下方法,但它没有按我的意愿工作。

awk '
BEGIN {FS=" "}
{if ($0 ~ /\[2018/) {flag=1;date_ref=$1;time_ref=$2;}            }
{if ($0 ~ /REF_ID/ ) {t_ref=$2}                   }
{if ($0 ~ /C_ID/ ) {gcid_ref=$2}        }
{if (flag=1) print date_ref,time_ref,t_ref,gcid_ref,$0}
'

我得到的输出:

[2018 13:50]   [2018 13:50] ALI
[2018 13:50] X  REF_ID X 
[2018 13:50] X  A 3 
[2018 13:50] X Y C_ID Y 
[2018 13:50] X Y B 4 
[2018 14:00] X Y [2018 14:00] ALI
[2018 14:00] X Y C 3 
[2018 14:00] Z Y REF_ID Z 
[2018 14:00] Z Y D 1 
[2018 14:00] Z Y E 4 
[2018 14:00] Z T C_ID T 

要解决我认为必须将数据放入缓冲区,收集变量并合并它的问题..

你能帮我解决这个问题吗?如果你能解释你提供的代码,那将会很有帮助。

【问题讨论】:

  • 那些边界线也是输入/输出的一部分?
  • 那些边界线不是输入/输出的一部分。其简单的空格分隔数据
  • 同意 cmets 清理您的样本数据,但 pluse-uno,因为这比一般的第一个问题要好得多。并且您实际上已经尝试在发布之前解决您的问题。我会查看 awk 中的多行记录,并参考您需要的 $3、$7、$9 等。祝您好运。
  • 我已使用原始原始数据和测试所需的输出更新了帖子。
  • @Ed-Morton 任何 cmets?

标签: design-patterns awk pattern-matching


【解决方案1】:
$ cat tst.awk
/^\[/ {
    prt()
    time = $1 FS $2
}
{
    map[$1] = $2     # save every 1st field to 2nd field mapping,
                     # e.g. map["REF_ID"]="X", map["C_ID"]="Y", etc.
    rec[++numLines] = $0
}
END { prt() }
function prt(   lineNr) {
    for (lineNr=1; lineNr<=numLines; lineNr++) {
        # now just retrieve the 2nd field values by their 1st field names
        print time, map["REF_ID"], map["C_ID"], rec[lineNr]
    }
    numLines = 0
}

$ awk -f tst.awk file
[2018 13:50] X Y [2018 13:50] ALI
[2018 13:50] X Y REF_ID X
[2018 13:50] X Y A 3
[2018 13:50] X Y C_ID Y
[2018 13:50] X Y B 4
[2018 14:00] Z T [2018 14:00] ALI
[2018 14:00] Z T C 3
[2018 14:00] Z T REF_ID Z
[2018 14:00] Z T D 1
[2018 14:00] Z T E 4
[2018 14:00] Z T C_ID T

【讨论】:

    【解决方案2】:

    我相信您可能对此感兴趣:

    awk '($1 ~ /^\[/) && record { 
            string= date_ref OFS time_ref OFS t_ref OFS gcid_ref OFS
            gsub(ORS,ORS string, record)
            print string record 
            record=""
         }
        ($1 ~ /^\[/) { date_ref=$1; time_ref=$2 }
        ($1 == "REF_ID") { t_ref=$2 }
        ($1 == "C_ID")   { gcid_ref=$2 }
        { record = record ? record ORS $0 : $0 }
        END { string= date_ref OFS time_ref OFS t_ref OFS gcid_ref OFS
              gsub(ORS,ORS string, record)
              print string record 
        }' <file>
    

    哪个输出:

    [2018 13:50] X Y [2018 13:50] ALI
    [2018 13:50] X Y REF_ID X 
    [2018 13:50] X Y A 3 
    [2018 13:50] X Y C_ID Y 
    [2018 13:50] X Y B 4 
    [2018 14:00] Z T [2018 14:00] ALI
    [2018 14:00] Z T C 3 
    [2018 14:00] Z T REF_ID Z 
    [2018 14:00] Z T D 1 
    [2018 14:00] Z T E 4 
    [2018 14:00] Z T C_ID T
    

    上述代码的想法是在打印任何内容之前将record 构建到内存中。在构建记录时,您可以选择相关信息,例如 date_ref time_reft_refgcid_ref

    1. ($1 ~ /^\[/) &amp;&amp; record 当记录开始时(由以[ 开头的行表示),您必须根据您选择的信息对上一条记录执行操作。 (除非它是空的)

      1. string= date_ref OFS time_ref OFS t_ref OFS gcid_ref OFS:在每一行之前构建一个你想要放置的stringOFS 默认是一个空格)
      2. gsub(ORS,ORS string, record)ORS string 替换所有换行符(默认值ORS
      3. print string record:: 打印前面有字符串的记录 它作为第一行还没有前面的字符串。
      4. record="" 重置record,从现在开始,您将创造新记录。
    2. ($1 ~ /^\[/) { ... }($1 == "REF_ID"){...}($1 == "C_ID") { }:在满足正确条件(即第一个字段等于或匹配适当的事物)时提取相关信息。

    3. { record = record ? record ORS $0 : $0 } 通过将当前行附加到记录并在其间添加换行符来构建记录(ORS 默认为换行符)。请注意,您必须检查记录是否为空,以免开头有多余的ORS

    4. END你还需要打印最后一条记录。再次执行步骤 1 中的所有操作。

    【讨论】:

    • 不幸的是它不起作用。在用反斜杠+括号修复括号 [ 字符后,我只得到了第一个块的输出,第二个块没有显示..
    • @DudeSkywalk 已修复!
    • @kvantour 它有效。如果您不介意,请解释一下代码,以便我了解它是如何工作的?
    • @DudeSkywalk 解释已添加
    • idk 如果它可能发生但如果由于gsub(ORS,ORS string, record)而在构成string 的输入部分中存在&amp; 则会失败
    猜你喜欢
    • 2016-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    相关资源
    最近更新 更多