sed和它是可选符号的正则表达式

时间:2015-05-21 08:56:58

标签: regex sed

我正在编写一个脚本,根据提示列表将大型FLAC音频文件拆分成小块。我使用cueprint来确定标签信息,但在某些情况下它不提供我需要的东西,我需要使用sed直接从cue文件中挖掘信息。现在我和GENRE打架了。它的问题在于它有不同的方式:

REM GENRE "Gothic"
REM GENRE Gothic

似乎都是标准的,但很难解析。 对于第二种情况,如

sed -nr -e "s/^(REM GENRE )(.*)\r/\2/p" *.cue

完美地工作并按预期返回Gothic。但是对于第一种情况,“Gothic”被归还,这不是我不会穿羽毛处理的。 那么,你会说“在正则表达式的第一和第三部分中使用”可选的“引号,就像这样

sed -nr -e "s/^(REM GENRE \"?)(.*)\"?\r/\2/p" *.cue

但是这不能按预期工作,结果是

Gothic"

带尾随双引号。

任何想法如何使用sed解析带引号和未带引号的字符串?

3 个答案:

答案 0 :(得分:2)

sed贪婪地匹配。当您匹配(.*)"?时,.*匹配Gothic""?匹配空字符串。您必须从.*字符串中排除双引号,例如

sed -nr 's/^REM GENRE "?([^"]*)"?\r?/\1/p' *.cue

请注意,这会导致引用带引号的字符串出现问题,例如"Goth\"ic"。为了避免这个问题,需要更大的枪支。我建议

sed -nr '/^REM GENRE "?(([^"]|\\")*)"?\r?/ { s//\1/; s/\\"/"/g; p; }'

那是

/^REM GENRE "?(([^"]|\\")*)"?\r?/ {   # if a line contains the pattern
  s//\1/                              # isolate the capturing group
  s/\\"/"/g                           # unescape quotes
  p                                   # then print.
}

请注意正则表达式中的([^"]|\\")*与非引号字符和转义引号相匹配。

答案 1 :(得分:1)

将中间的(.*)更改为([^\"]*)以排除引号。

答案 2 :(得分:1)

你可以使用这个,

sed -nr -e 's/^(REM GENRE )"?([^"\r]*)/\2/p' *.cue