在文件中使用 shell 脚本查找并替换/更改一行中的多个字符串

在文件中使用 shell 脚本查找并替换/更改一行中的多个字符串

我是 shell 脚本新手

我拥有的是一个日志文件,每一行都像下面的条目一样开始,

[2021.04.27.17:03:43.813]: ERROR -
[2021.04.27.17:04:36.790]: SUCCESS -

所需的新文件输出是

2021-04-27 17:03:43 813,ERROR,
2021-04-27 17:04:36 790,SUCCESS,

我编码的是

while read a; do
    echo ${a//"["/""}
    echo ${a//"]"/""}
done < xms.log > resultlog.txt

上面的代码删除了备用行的方括号,这意味着从第一行“[”开始的方括号被删除,从第二行“]”结束的括号被删除,我希望两者都从所有行中删除。不仅如此,我想更改为连字符的点已在上面的示例中显示。

答案1

使用流编辑器sed修改文本文件:

sed 's/\./-/;s//-/;s// /;s// /;s/: /,/;s/ -/,/;s/\[//;s/]//' xms.log > resultlog.txt

该脚本仅包含s形式的替代命令s/pattern/replacement/,以分号分隔。s/\./-/用破折号替换第一个点。您还想替换下一个点,因此不需要重复该模式,只需将模式留空并写入s//-/.以同样的方式完成所有其他所需的更换。如果需要匹配正则表达式语法中具有特殊含义的字符,则需要使用反斜杠:\.和进行转义\[

更具可读性,也可以写成

sed 's/\./-/
     s/\./-/
     s/\./ /
     s/\./ /
     s/: /,/
     s/ -/,/
     s/\[//
     s/]//' xms.log > resultlog.txt

答案2

要处理 shell 脚本中的文本,您需要调用文本处理工具(例如或 )sed来处理整个输入,而不是在输出的每一行上多次调用不充分的工具(例如或 ) 。awkperlreadecho

在这里,我将使用正则表达式来匹配输入并提取相关字段并根据需要重新格式化。perl最适合正则表达式匹配:

perl -lpe '
    $_ = "$1-$2-$3 $4 $5,$6," if
     m{^\[(\d\d\d\d)\.(\d\d)\.(\d\d)\.(\d\d:\d\d:\d\d)\.(\d\d\d)\]: (\w+)}
  ' < input.txt > output.txt

其中,在正则表达式语法中:

  • ^匹配主题的开头(此处的行)
  • \[匹配一个[字符。
  • \d匹配十进制数字。
  • \.匹配文字.字符。
  • \w+w尽可能多地匹配一个或多个顺序字符(此处为字母 1 或下划线)。
  •  :分别匹配自己。
  • (...)用于捕获$1, $2...中匹配的内容

这将重新格式化与模式匹配的行,并保留其他行(如果有)。


¹ 仅限于 ASCII 数字 (0123456789),因为我们没有告知perl要在 Unicode 模式下工作,也没有按照区域设置的编码进行工作,因此它不会包含其他十进制数字,例如

相关内容