2

我认为我对正则表达式的使用非常好,但是这个看起来非常棘手。

我想修剪所有空格,除了 "" 和 [] 字符之间的空格。

我使用了这个正则表达式("[^"]*"|\S+)\s+,但确实将我的日志的[06/Jan/2021:17:50:09 +0300]部分分成了两个块。

这是我的整个日志行:

[06/Jan/2021:17:50:09 +0300] "" 10.139.3.194 407 "CONNECT clients5.google.com:443 HTTP/1.1" "" "-" "" 4245 75 "" "" "81" ""

结果我使用 sed 命令基于我的正则表达式(用逗号替换空格):

[06/Jan/2021:17:50:09,+0300],"",10.139.3.194,407,"CONNECT clients5.google.com:443 HTTP/1.1","","-","",4245,75,"","","81",""

最后我想要的结果:

[06/Jan/2021:17:50:09 +0300],"",10.139.3.194,407,"CONNECT clients5.google.com:443 HTTP/1.1","","-","",4245,75,"","","81",""
4

2 回答 2

3

由于这些样本输入看起来像日志,因此考虑到它们将始终采用相同的格式;有了这个,您可以尝试以下awk代码,在 GNU 中显示的示例中编写和测试awk

awk -v FPAT='[^]]*\\]|"[^"]*"|([0-9]+\\.){3}[0-9]+|[0-9]{2,4}' -v OFS="," '{$1=$1} 1'  Input_file

解释:

  • 简单的解释是awk在这里使用 GNU。其中有FPAT可用的选项。
  • 以正则表达式形式设置字段分隔符的选项。它根据 FPAT 中提到的正则表达式匹配事物,并相应地每行生成字段。
  • 然后为所有行设置OFS(输出字段分隔符) 。,
  • 在重置行的主程序中awk(通过重置第一个字段)根据 OP 的要求对其应用 OFS 值。这将确保逗号应仅根据需要输出。

正则表达式的解释:

[^]]*\\]               ##Matching everything till ] followed by ] here.
|                      ##OR
"[^"]*"                ##Matching from " till first occurrence of " everything between them including "
|                      ##OR
([0-9]+\\.){3}[0-9]+   ##Matching digits followed by dot 3 times followed by digits
|                      ##OR
[0-9]{2,4}             ##Matching 2 to 4 digits here.
于 2021-11-15T12:36:08.803 回答
0

\[[^][]*]您可以通过添加作为第 1 组模式的替代方案来匹配方括号之间的字符串:

sed -E 's/(\[[^][]*]|"[^"]*"|\S+)\s+/\1,/g'

现在,POSIX ERE(使用该-E选项启用语法)模式匹配

  • (\[[^][]*]|"[^"]*"|\S+)- 第 1 组:任一个
    • \[[^][]*]- 一个[字符,然后是零个或多个字符[]然后是一个]字符
    • |
    • "[^"]*"- 一个"字符,零个或多个字符",然后是一个"字符
    • |- 或者
    • \S+- 一个或多个非空白字符
  • \s+- 一个或多个空格

查看在线演示

#!/bin/bash
s='[06/Jan/2021:17:50:09 +0300] "" 10.139.3.194 407 "CONNECT clients5.google.com:443 HTTP/1.1" "" "-" "" 4245 75 "" "" "81" ""'
sed -E 's/(\[[^][]*]|"[^"]*"|\S+)\s+/\1,/g' <<< "$s"

输出:

[06/Jan/2021:17:50:09 +0300],"",10.139.3.194,407,"CONNECT clients5.google.com:443 HTTP/1.1","","-","",4245,75,"","","81",""
于 2021-11-15T12:21:46.953 回答