【问题标题】:How to use sed to replace strings in piped input with command outputs using regular expressions如何使用 sed 使用正则表达式将管道输入中的字符串替换为命令输出
【发布时间】:2018-08-15 17:32:23
【问题描述】:

我正在尝试使用 sed 正确解析 auditd 记录的输出。这些已经编码了十六进制、长时间戳和 UID/AUID,我需要通过命令对其进行解码/翻译。

我正在使用管道,因为我必须将它传送到系统日志。 我已经走到这一步了:

sed -r "s@msg=([A-Z0-9]*)\$@msg=$(xxd -r -p <<< \1)@"

示例输入:

[IRRELEVANT STUFF] msg=7468697320697320612073616D706C652074657374

问题在于 sed 没有“展开”捕获组,并且嵌套命令接收到错误的参数/输入。

xxd 应该接收7468697320697320612073616D706C652074657374 而不是\1

我以孤立的方式对此进行了测试,这确实是正在发生的事情。

帮助!谢谢!!

【问题讨论】:

  • 模式中的文字$是什么?
  • 那是匹配正则表达式的字符串/行终止符
  • 是的,我没有注意到双引号。你可以试试这样的sed -r "s@msg=([A-Z0-9]*).*|.@\1@g" | xxd -r -p。 (没有添加$g 标志。)
  • 恐怕这行不通,因为我正在尝试在线编辑,完整的输出(替换后)将被输入到不同的命令中
  • sed 的输出将是\1。所以正确的字符串将被传递给xxd

标签: regex bash shell sed audit


【解决方案1】:

sed 用于执行 s/old/new,仅此而已,其他任何事情都只需使用 awk。使用 GNU awk 将第三个参数匹配():

awk '
match($0,/(.*msg=)([[:alnum:]]+)$/,a) {
    cmd = "xxd -r -p <<< " a[2]
    $0 = a[1] ((cmd | getline line) > 0 ? line : "ERROR")
    close(cmd)
}
{ print }
'

以上假设调用您的xxd 命令的语法正是您在 sed 脚本中使用的语法。我的系统上没有xxd,但这里使用wc -c 来显示脚本的工作原理:

$ wc -c <<< 7468697320697320612073616D706C652074657374
43

$ awk '
match($0,/(.*msg=)([[:alnum:]]+)$/,a) {
    cmd = "wc -c <<< " a[2]
    $0 = a[1] ((cmd | getline line) > 0 ? line : "ERROR")
    close(cmd)
}
{ print }
' file
[IRRELEVANT STUFF] msg=43

【讨论】:

  • 这看起来很棒,正是我需要的,但我似乎无法运行它,我遇到了语法错误。
  • 我有一个额外的括号。我修复了这个问题并更新了我的答案以显示脚本工作但调用了我系统上的不同 shell 命令。
【解决方案2】:

我认为你需要这样做:

sed -r "s/.*msg=([A-Z0-9]*).*/xxd -r -p <<< \1/e" input

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-20
    • 2013-02-21
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 2019-10-10
    • 2020-04-25
    • 1970-01-01
    相关资源
    最近更新 更多