英文:
How to use sed to only replace first match
问题
我试图在sed中应用一系列的s/foo/baz/g
,并且我希望它在第一次匹配时停止处理单行,执行替换,然后移动到下一行。
基本上,我会将最具体的匹配放在顶部,只有在无法匹配其他任何内容时,才会退回到最通用的模式。
示例sed文件:
s/Execution error for request ([0-9]+). Reason: (ESS-[0-9]+) Job logic indicated a system error occurred while executing an asynchronous java job for request ([0-9]+). Job error is/ /g
s/Execution error for request ([0-9]+). Reason: com.jbo.AttrValException: (JBO-[0-9]+): Attribute RequestId is required./1 /2/p
s/Execution error for request ([0-9]+). .*//p
示例输入:
Execution error for request 12345678. Reason: com.jbo.AttrValException: JBO-27035: Attribute RequestId is required.
Execution error for request 87546213. Reason: ESS-07033 Job logic indicated a system error occurred while executing an asynchronous java job for request 87546213. Job error is: null.
Execution error for request 54789632. Reason: null
期望的输出:
87546213 ESS-07033
12345678 JBO-27035
54789632
正如你所见,这个表达式是最容忍的,会匹配所有三个,但我需要先尝试并重新映射其他更具体的表达式。我看到的行为是sed匹配,然后将新变形的值传递给下一个表达式,依此类推。所以,它变成了:f(g(h(x)))
而不是f(x)或g(x)或h(x)
。
这是我运行sed的方式:
sed -E -n -f $filter $input
英文:
I am trying to apply a series of s/foo/baz/g
in sed, and I want it to stop processing a single line on the first match, do the replacement, and then move to the next line.
Basically, I will put the most specific matches at the top and only if it can't match anything else, should it fall back to the most generous pattern
Example sed file:
s/Execution error for request ([0-9]+). Reason: (ESS-[0-9]+) Job logic indicated a system error occurred while executing an asynchronous java job for request ([0-9]+). Job error is/ /g
s/Execution error for request ([0-9]+). Reason: com.jbo.AttrValException: (JBO-[0-9]+): Attribute RequestId is required./1 /2/p
s/Execution error for request ([0-9]+). .*//p
Example input:
Execution error for request 12345678. Reason: com.jbo.AttrValException: JBO-27035: Attribute RequestId is required.
Execution error for request 87546213. Reason: ESS-07033 Job logic indicated a system error occurred while executing an asynchronous java job for request 87546213. Job error is: null.
Execution error for request 54789632. Reason: null
Expected output:
87546213 ESS-07033
12345678 JBO-27035
54789632
As you can see, the expression is the most forgiving and would match all 3, but I need the other more specific ones to be tried and remapped first. The behavior I am seeing is that sed it matching, then passing to the next expression the newly morphed values, etc. So, it's becoming: f(g(h(x)))
instead of f(x) or g(x) or h(x)
here is how I am running sed:
sed -E -n -f $filter $input
答案1
得分: 2
使用 t
命令。
修复您的脚本:
s/Execution error for request ([0-9]+). Reason: (ESS-[0-9]+) Job logic indicated a system error occurred while executing an asynchronous java job for request ([0-9]+). Job error is.*/ /p
t
s/Execution error for request ([0-9]+). Reason: com.jbo.AttrValException: (JBO-[0-9]+): Attribute RequestId is required./ /p
t
s/Execution error for request ([0-9]+). .*//p
t
> [2addr]t [label]
>
> 测试。如果自最近读取输入行或执行 t 后已进行了任何替换,则分支到带有 label 的命令动词。如果未指定 label,则分支到脚本的末尾。
英文:
Use the t
command.
Fixing your script:
s/Execution error for request ([0-9]+). Reason: (ESS-[0-9]+) Job logic indicated a system error occurred while executing an asynchronous java job for request ([0-9]+). Job error is.*/ /p
t
s/Execution error for request ([0-9]+). Reason: com.jbo.AttrValException: (JBO-[0-9]+): Attribute RequestId is required./ /p
t
s/Execution error for request ([0-9]+). .*//p
t
From: POSIX specification:
> [2addr]t [label]
>
> Test. Branch to the : command verb bearing the label if any substitutions have been made since the most recent reading of an input line or execution of a t. If label is not specified, branch to the end of the script.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论