使用sed仅在正则表达式子字符串内替换

时间:2013-10-10 18:42:44

标签: regex replace sed

我有一个日志,我想在regexp匹配文本中应用替换。

示例,请记下此日志行:

date machine  text random text and yet more random text - status code

我希望o在文本区域内用_替换所有空格,而不替换日志中的所有其他空格。输出将是:

date machine  text_random_text_and_yet_more_random_text - status code

为了匹配我想要替换的区域,我有这个正则表达式:

/machine \(.*\) - /

由于文本不是标准的,我可以有一个空格到20,所以很难直接匹配它,所以我匹配子串的开始和结束。

尝试使用它我尝试了这个:

sed `/machine \(.*\) - /   s/ /_/g '  logfile

但当然,它将替换日志中的所有空格,而不仅仅是匹配的子字符串。

我设法用awk做了,通过迭代和打印每个字段,直到我找到machine,我在那里更改OFS="_"并在找到-时将其恢复到空格。它有效...但是,如果可以使用sed解决这个问题,我很好奇。

由于

5 个答案:

答案 0 :(得分:1)

由于在文本之前有两个空格,您希望使用下划线和空格 - 空格,您可以这样做:

awk -F "  | - " '/machine/ {gsub(/ /,"_",$2)}1' file
date machine text_random_text_and_yet_more_random_text status code

答案 1 :(得分:1)

这可能适合你(GNU sed):

sed -r 's/(\S+\s+){2}/&\n/;s/\s+-/\n&/;h;y/ /_/;G;s/.*\n(.*)\n.*\n(.*)\n.*\n/\2\1/' file

答案 2 :(得分:0)

这是一个gnu-awk命令来解决这个问题:

s='date machine text random text and yet more random text - status code'
awk '{gsub(/ /, "_", $2); print $1 " machine " $2 " - " $3}' FS='machine *| *- *' <<<"$s"

date machine  text_random_text_and_yet_more_random_text - status code

答案 3 :(得分:0)

另一个awk解决方案可能是:

awk '{
    # Capture the stringpart in `a`rray
    match($0,"machine  (.*) -",a)
    # Make the changes
    gsub(" ","_",a[1])
    print gensub("machine (.*) -","machine  " a[1] " -","g")
}' INPUTFILE

答案 4 :(得分:0)

的Perl:

echo "date machine  text random text and yet more random text - status code" | 
perl -pe 's/(?<=machine  )(.*)(?= - )/ ($repl = $1) =~ s{\s}{_}g; $repl /e'
date machine  text_random_text_and_yet_more_random_text - status code