Sed:特定的精确两个匹配

Sed: specific exact two match

我在文件中有这一行。单词之间的空格可以是制表符或空格

#define FN_AUTO_FN_FNSECTOR   Function(2)     /* FN_ comment*/

我希望输出是这样的:

2:"FN_AUTO_FN_FNSECTOR",

我有这个代码:

echo -e "#define \t \t\t FN_AUTO_FN_FNSECTOR \t\t\t  Function(2)\t     /* FN_ comment*/" |sed "s/.*\(\([[:blank:]]\)FN_*[_a-zA-Z]*\).[^ ].*(\([^\)]*\)).*/:\"\",/"

但输出是在引号和 FN_AUTO_FN_FNSECTOR 之间有空格:

2:"     FN_AUTO_FN_FNSECTOR",

如何避免?解决方案必须是稳健的空格或制表符,不得影响选择。我的解决方案必须在 sed 中,最好在一个命令中。

解决方案: 感谢亚伦。我更喜欢的解决方案是这个

echo -e "#define \t\t\r FN_AUTO_FN_FNSECTOR \t\r\t\t  Function(2)\t     /* FN_ comment*/" |sed "s/.*\s\(FN_*[_a-zA-Z]*\).[^ ].*(\([^\)]*\)).*/:\"\",/"

在您的 sed 命令中,以您的拳头开口 \( 开头的第一个捕获组包含 [[:blank:]] class,它与 FN_AUTO_FN_FNSECTOR 之前的空格相匹配。

我建议使用以下命令:

sed -E 's/.*\s(FN_*[_a-zA-Z]*).*\(([^)])\).*/:\""/'

已测试 here

在此命令中,我使用 -E 切换到扩展正则表达式,其中 (...) 表示捕获组,而 \(...\) 表示文字括号。它还使我(至少在现代 GNU sed 上)能够使用 \s 来表示空白。

使用sed

$ sed 's/[^[:space:]]*[[:space:]]\([^[:space:]]*\)[^(]*(\(.\).*/:"",/' input_file
2:"FN_AUTO_FN_FNSECTOR",

你可以使用

sed -E 's/.*[[:blank:]](FN[^[:blank:]]*)[[:blank:]]+[^[:blank:]]+\(([^()])\).*/:"",/'

如果你有 GNU sed,你可以用 \s(任何空格)替换 [[:blank:]],用 \S(任何 non-whitespace)替换 [^[:blank:]] :

sed -E 's/.*\s(FN\S*)\s+\S+\(([^()]*)\).*/:"",/'

参见 online demo:

#!/bin/bash
s='#define FN_AUTO_FN_FNSECTOR   Function(2)     /* FN_ comment*/'
sed -E 's/.*[[:blank:]](FN[^[:blank:]]*)[[:blank:]]+[^[:blank:]]+\(([^()]*)\).*/:"",/' <<< "$s"
## => 2:"FN_AUTO_FN_FNSECTOR",

请注意,-E 选项允许 POSIX ERE 语法,其中未转义的 + 是一个 一个或多个 量词,并定义捕获组你需要未转义的括号对。

图案详情:

  • .* - 任何文本
  • [[:blank:]] - 水平空白字符
  • (FN[^[:blank:]]*) - 第 1 组:FN 和零个或多个 non-whitespace 个字符
  • [[:blank:]]+ - 一个或多个水平空白字符
  • [^[:blank:]]+
  • \( - 文字 ( 字符(在 POSIX BRE 中,不应转义,但在 ERE 中,必须转义)
  • ([^()]*) - 第 2 组:除 () 之外的任何零个或多个字符(请注意括号表达式中的 ()不需要转义任何 POSIX(以及我所知道的所有 non-POSIX)正则表达式)
  • \) - POSIX ERE
  • 中的文字 )
  • .* - 任何文本