合并一些以特殊字符开头的行

合并一些以特殊字符开头的行

我有一些这样的日志:

2023-11-15T08:59:28.000000+00:00 database-1 # Time: 231115  8:59:28
# User@Host: rdsadmin[rdsadmin] @ localhost []
# Thread_id: 3  Schema:   QC_hit: No
# Query_time: 0.000123  Lock_time: 0.000000  Rows_sent: 1  Rows_examined: 0
# Rows_affected: 0  Bytes_sent: 49
SET timestamp=1700038768;
SET STATEMENT max_statement_time=60 FOR SELECT 1;

你能帮我将一些以#字符开头的行合并到一行中,如下所示:

2023-11-15T08:59:28.000000+00:00 database-1 # Time: 231115  8:59:28# User@Host: rdsadmin[rdsadmin] @ localhost []# Thread_id: 3  Schema:   QC_hit: No# Query_time: 0.000123  Lock_time: 0.000000  Rows_sent: 1  Rows_examined: 0# Rows_affected: 0  Bytes_sent: 49
SET timestamp=1700038768;
SET STATEMENT max_statement_time=60 FOR SELECT 1;

我使用awsclitail 并希望显示来自 aws rds 的默认日志。

我尝试过这个命令但不起作用

aws logs tail /aws/rds/instance/database-1/slowquery --log-stream-names database-1 --follow |  sed ':a;N;$!ba;s/\n\#/ #/g'

答案1

使用awk

$ awk '
  {
    printf "%s", ((/^#/ || NR==1) ? "" : ORS )$0
  }
  END {
    if (NR) print ""
  }'

答案2

使用任何 awk:

$ awk '
    /^#/ { rec = rec OFS $0; next }
    NR>1 { print rec }
    { rec = $0 }
    END { print rec }
' file
2023-11-15T08:59:28.000000+00:00 database-1 # Time: 231115  8:59:28 # User@Host: rdsadmin[rdsadmin] @ localhost [] # Thread_id: 3  Schema:   QC_hit: No # Query_time: 0.000123  Lock_time: 0.000000  Rows_sent: 1  Rows_examined: 0 # Rows_affected: 0  Bytes_sent: 49
SET timestamp=1700038768;
SET STATEMENT max_statement_time=60 FOR SELECT 1;

通过上面的内容,我们逐行构建并存储多行记录,rec并在下一条记录开始时打印它。这样,如果您在打印之前需要对记录执行任何操作,则可以将其保存在rec.如果您需要在打印之前保留单独的行来执行某些操作,rec那么只需调整上面的内容即可在行之间存储记录分隔符:

awk '
    /^#/ { rec = rec RS $0; next }
    NR>1 { prt() }
    { rec = $0 }
    END { prt() }
    function prt() { gsub(RS,OFS,rec); print rec }
' file
2023-11-15T08:59:28.000000+00:00 database-1 # Time: 231115  8:59:28 # User@Host: rdsadmin[rdsadmin] @ localhost [] # Thread_id: 3  Schema:   QC_hit: No # Query_time: 0.000123  Lock_time: 0.000000  Rows_sent: 1  Rows_examined: 0 # Rows_affected: 0  Bytes_sent: 49
SET timestamp=1700038768;
SET STATEMENT max_statement_time=60 FOR SELECT 1;

然后在该函数中,您可以获得有关构造的prt()单独行的所有信息。rec

答案3

使用ed下面的命令,我们将以#字符开头的任何行与上一行连接起来:

g/^#/ -,. j

该命令的作用是将命令应用于-,. j与正则表达式匹配的每一行^#。该j命令连接上一行 ( -) 和当前行 ( .)。

添加,p以打印整个缓冲区并Q退出:

$ printf '%s\n' 'g/^#/ -,. j' ,p Q | ed -s file
2023-11-15T08:59:28.000000+00:00 database-1 # Time: 231115  8:59:28# User@Host: rdsadmin[rdsadmin] @ localhost []# Thread_id: 3  Schema:   QC_hit: No# Query_time: 0.000123  Lock_time: 0.000000  Rows_sent: 1  Rows_examined: 0# Rows_affected: 0  Bytes_sent: 49
SET timestamp=1700038768;
SET STATEMENT max_statement_time=60 FOR SELECT 1;

将两个命令,p和更改Q为单个命令wq(或分别更改为wq),将编辑的缓冲区写回原始文件并退出。

答案4

aws logs tail /aws/rds/instance/database-1/slowquery --log-stream-names database-1 --follow | sed ':a;N;$!ba;s/\n#/#/g'

相关内容