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

查看:100
本文介绍了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)的形式显示ID(通常为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无法将regex节(\ 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.只是为了解释.以下表达式有效,但是当然其中不传递任何参数:

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.

基本上,遵循以下原则:

Basically, something along these lines:

sed 's/\(.*\), 0x\([0-9A-F]*\)$/s%ERRORID:0x\2%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:0x\2%ERROR:\1%g/' errors.txt >errors.sed
# Use it many times
sed -f errors.sed logfile.txt

您还可以在errors.sed的顶部添加#!/usr/bin/sed -f并将其添加到chmod +x,以使其成为独立的命令脚本.

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天全站免登陆