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 中的文字 )
.*
- 任何文本
我在文件中有这一行。单词之间的空格可以是制表符或空格
#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 中的文字 .*
- 任何文本
)