sed 表达式中的命令替换 [英] Command substitution within sed expression

查看:28
本文介绍了sed 表达式中的命令替换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 bash/sed 没什么问题.我需要能够在 sed 表达式中使用命令替换.我有两个大文本文件:

I'm having little problem with bash/sed. I need to be able to use command substitution within sed expression. I have two big text files:

  • 首先是 logfile.txt,它有时*按 ID(0xdeadbeef 是常见示例)显示错误消息,格式为 ERRORID:0xdeadbeef

  • first is logfile.txt which sometimes* shows error messages by ID (0xdeadbeef is common example) in format ERRORID:0xdeadbeef

second errors.txt 将错误消息成对存储 LONG_ERROR_DESCRIPTION, 0xdeadbeef

second errors.txt has error messages stored in pairs LONG_ERROR_DESCRIPTION, 0xdeadbeef

我试图使用 sed 和 bash 命令替换来完成任务:

I was trying to use sed with bash command substitution to do the task:

cat logfile.txt | sed "s/ERRORID:(0x[0-9a-f]*)/ERROR:$(cat errors.txt |
    grep 1 | grep -o '^[A-Z_]*' )/g"

(^^^ 这当然应该在一行中)

(^^^ this should be in one line of course)

如果它可以工作,那么我可以获得更好的日志文件版本,并提供更好的错误信息.

If it would work then I could get little nicer version of logfile with better error info.

   Lot's of meaningless stuff ERRORID:0xdeadbeef and something else =>
=> Lot's of meaningless stuff ERROR:LONG_ERROR_DESCRIPTION and something else 

但事实并非如此.问题是 sed 无法注入"正则表达式部分 (1) 到命令替换中.我的其他选择是什么?我知道可以先构建 sed 表达式或以其他方式构建,但我想避免多次解析这些文件(它们可能很大).

But it doesn't. The problem is that sed is unable to "inject" regex section (1) into command substitution. What are my other options? I know that it's possible to build sed expression first or do it other way but I would like to avoid parsing those files several times (they can be huge).

一如既往地非常感谢您的帮助.

As always big thanks for any help.

*日志文件中没有真正的格式.没有使用不一致的节、列、制表符/逗号分隔

*there is no real formatting inside logfile. No sections, columns, tab/coma-separation are used inconsistently

附注.只是为了解释.以下表达式有效,但当然没有参数在其中传递:

PS. Just to explain. Following expression works, but of course there is no argument passing within it:

echo "my cute cat" | sed "s/cat/$(echo dog)/g"

推荐答案

您可以从错误消息目录中创建一个 sed 脚本,然后将该 sed 脚本应用到日志文件中.

You can create a sed script from the error message catalog, then apply that sed script to the log file.

基本上是这样的:

sed 's/(.*), 0x([0-9A-F]*)$/s%ERRORID:0x2%ERROR:1%g/' errors.txt |
sed -f - logfile.txt

第一个 sed 脚本的输出应该是这样的:

The output from the first sed script should be something like this:

s%ERRORID:0x00000001%ERROR:Out of memory%
s%ERRORID:0x00000002%ERROR:Stack overflow%
s%ERRORID:0x00000031%ERROR:values of beta may cause dom%

也就是说,一个新的 sed 脚本,它为目录中的每个错误代码指定一个替换.

That is, a new sed script which specifies a substitution for each error code in the catalog.

sed 有不同的方言,因此这可能需要稍作调整.我认为 Linux 上的 sed 在将正则表达式中的括号分组之前应该使用反斜杠,并且很乐意将标准输入作为 -f 选项的参数.不过,这不能移植到其他 Unices(但如果您需要可移植性,可以用 Perl 代替 sed).

There are different dialects of sed so this may require minor tweaking. The sed on Linux I believe should use backslash before grouping parentheses in regular expressions, and gladly tolerate standard input as the argument to the -f option. This is not portable to other Unices, though (but you could substitute Perl for sed if you need portability).

*如果错误消息相当静态,和/或您想从标准输入读取日志,请将生成的脚本保存在文件中;

* If the error messages are fairly static, and/or you want to read the log from standard input, save the generated script in a file;

# Do this once
sed 's/(.*), 0x([0-9A-F]*)$/s%ERRORID:0x2%ERROR:1%g/' errors.txt >errors.sed
# Use it many times
sed -f errors.sed logfile.txt

您也可以在 errors.sedchmod +x 的顶部添加 #!/usr/bin/sed -f使其成为一个独立的命令脚本.

You could also add #!/usr/bin/sed -f at the top of errors.sed and chmod +x it to make it into a self-contained command script.

这篇关于sed 表达式中的命令替换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆