如何在特定模式之间获取数据?

时间:2018-01-27 02:30:45

标签: awk

如何从有效负载日志中打印格式化数据?

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        boards.remove(at: indexPath.row)
        // use async to avoid showing white background.
        DispatchQueue.main.async {
            tableView.deleteRows(at: [indexPath], with: .automatic)
        }
    }
}

我正在寻找的输出是 -

Time: 1970-01-01T00
ID:sdafasdfsladfsdfas
Key:sadfljasdkfsf
record {'record1:32423
 record2:45245
 record3:dasfas'
}
Time: 1970-01-01T001
ID:sdafasdfsladfsdfas1
Key:sadfljasdkfsf1
record {'record1:32423
 record2:452451
 record3:dasfas1'
}

我能够使用多个命令来实现输出,但我正在寻找一种正确的方法来在一个命令中获取它。

2 个答案:

答案 0 :(得分:2)

您能否请关注awk并告诉我这是否对您有所帮助。

解决方案1: 记录字符串的输出应来自第1条记录的起点:

awk -v s1="'" -F' |:' '    ##creating a variable named s1 whose value is single quote and setting field separator as space or colon here.
$0 ~ s1{                   ##Checking if line is having s1 variable in it then do following:
  gsub(s1,"")}             ##Global substituting s1 value with NULL in current line.
{
  sub(/^ +/,"")            ##Substituting initial space with NULL in all lines(if present).
}
/^}/{                      ##Checking if a line starts from } then do following:
  len=i=add=val=""         ##Nullifying variables len,i,add and val here.
}
/Time/||/ID/||/Key/{       ##Checking condition here if a line has string(s) Time or ID or Key in it then do following:
  val=val?val "|" $NF:$NF  ##Creating variable named val whose value is concatenating its own value each time with current lines last field value.
}
/^record /{                ##Checking condition here if a line is having string record in it and it starts from it then do following:
  sub(/{/,"");             ##Substitute { with NULL to current line.
  add=length($NF)>prev?length($NF)-prev:(prev?prev:prev-length($NF)); ##creating variable named add and checking condition length($NF)>prev if this is true then do length($NF)-prev otherwise check if variable prev is present then do prev or do a prev-length($NF).
  val=val?val "|" $2 ":"  $3:$2 ":" $3; ##Creating variable val here whose value is concatenating its own values and will add $2 ":" $3 each time too.
  prev=length($NF)         ##creating variable named prev which will have the length of last field in it.
}
/^record[0-9]+/{           ##Checking condition here if a line starts from string record and followed by digits then do following:
  add=length($NF)>prev?length($NF)-prev:prev-length($NF); ##Creating variable named add here where checking condition length($NF)>prev if it is true then do length($NF) or do prev-length($NF) here.
  len=length(val)+add;     ##Creating variable named len here whose value is addition of add and length of variable val.
  if(++i==1){              ##Checking condition if variable i value is 1 here then do following:
    print val};            ##Printing the value of variable val here.
  printf("%+"len"s\n",$0)  ##Using the printf to print the value of len to print spaces till the length of len and then printing current line.
}
' length_question          ##Mentioning the Input_file name here.

输出如下。

1970-01-01T00|sdafasdfsladfsdfas|sadfljasdkfsf|record1:32423
                                               record2:45245
                                               record3:dasfas
1970-01-01T001|sdafasdfsladfsdfas1|sadfljasdkfsf1|record1:32423
                                                  record2:452451
                                                  record3:dasfas1

解决方案第二: 哪个OP发布的记录字符串应该从第一个记录字符串的位置开始:

awk -v s1="'" -F' |:' '  ##creating a variable named s1 whose value is a single quote and creating field separator as space OR colon here.
$0 ~ s1{                 ##Checking if a line has variable s1(single quote) in it, if yes that do following:
  gsub(s1,"")            ##Globally substitute s1 with NULL in current line.
}
{
  sub(/^ +/,"")          ##Substituting initial space with NULL for every line in case it is present on it.
}
/^}/{                    ##Checking if a line is starting from } then do following:
   len=i=add=val=""      ##Nullifying variables named len,i,add,val here.
}
/Time/||/ID/||/Key/{     ##Checking a condition if a line has string(s) either Time or ID or Key in it then do following:
   val=val?val "|" $NF:$NF ##creating variable named val here whose value will be concatenating with its own value and with a pipe delimiter.
}
/^record /{              ##Checking condition here if a line starts from string record then do following:
   sub(/{/,"");          ##Substituting { with NULL in current line then.
   add=length($NF)>prev?length($NF)-prev:(prev?prev:prev-length($NF)); ##Creating a variable named add, where we will check if variable prev value is less than length of current lines last field if yes then have its value as length($NF)-prev OR have its value as prev(if it is not null) or have it prev-length($NF) in it.
   val=val?val "|" $2 ":"  $3:$2 ":" $3; ##Creating variable named val whose value will be concatenating itself with the values of $2 ":" $3 in it.
   if(!prev_val){        ##Checking condition if variable named prev_val is NULL then do following:
     prev_val=length(val)}; ##creating variable prev_val whose value is length of variable val here.
   prev=length($NF)      ##creating variable named prev whose value is length of last field of current line.
}
/^record[0-9]+/{         ##Checking condition here if a line starts from string record and followis with digits in it then do following:
   add=length($NF)>prev?length($NF)-prev:prev-length($NF);##Creating variable namd add here checking if length($NF)>prev then make its value as length($NF)-prev or makeits value as prev-length($NF).
   len=prev_val+add;     ##Creating variable named len whose value is addition of variables prev_val and add.
   if(++i==1){print val} ##checking if variable i value is 1 here if yes then print varaible val here.
   printf("%+"len"s\n",$0) ##Printing variable lens value in printf to get the enough spaces on line with a new line.
}
' length_question        ##mentioning the Input_file name here.

输出如下:

1970-01-01T00|sdafasdfsladfsdfas|sadfljasdkfsf|record1:32423
                                               record2:45245
                                               record3:dasfas
1970-01-01T001|sdafasdfsladfsdfas1|sadfljasdkfsf1|record1:32423
                                               record2:452451
                                               record3:dasfas1

答案 1 :(得分:2)

Awk 解决方案:

awk -F': *' '/^(Time|ID|Key)/{ 
                 printf "%s|", $2; 
                 len += length($2)+1
            }
            /^record/{
                f=1; sub(/^[^{]+\{\047/, "");
                printf "%s\n", $0; next 
            }
            /\}/{ f=len=0 }
            f{ 
                gsub(/^ *|\047$/, "");
                printf "%+" len+length($0) "s\n", $0
            }' file
  • -F': *' - 字段分隔符
  • /^(Time|ID|Key)/ - 遇到其中一个关键键(TimeIDKey):
    • printf "%s|", $2 - 打印其值(由第二个字段$2显示),然后以|的形式打印,不会有换行符
    • len += length($2)+1 - 累计每个打印项目的长度(+1 - 包括尾随|字符)
  • /^record/ - 遇到主record行:
    • f=1 - 设置标记f,确保积极处理record部分
    • sub(/^[^{]+\{\047/, "") - 在字符串开头删除record {'序列
    • printf "%s\n", $0; next - 在先前打印的值之前打印record:<value>序列$0,以换行符\n结束
    • next - 跳转到下一条记录
  • /\}/{ f=len=0 } - 遇到}个字符(作为已处理部分的结尾) - 重置所有关键变量
  • f{ ... } - 关于积极处理的部分:
    • gsub(/^ *|\047$/, "") - 删除前导空格和/或尾随单引号'
    • printf "%+" len+length($0) "s\n", $0 - 使用长度$0作为格式缩进长度说明符打印下级记录序列len+length($0)

输出:

1970-01-01T00|sdafasdfsladfsdfas|sadfljasdkfsf|record1:32423
                                               record2:45245
                                               record3:dasfas
1970-01-01T001|sdafasdfsladfsdfas1|sadfljasdkfsf1|record1:32423
                                                  record2:452451
                                                  record3:dasfas1