infile.txt
我有一个包含以下字符串的文本文件:
[ A ]
1
2
[ B ]
3
[ C
4
5
[ D ]
我希望同时使用grep
和来打印以 开头和结尾的sed
行。因此我想要的输出是:[
]
grep
sed
[ A ]
[ B ]
[ D ]
作为现实检查,我将首先尝试打印包含以下内容的行[
:
grep "\[" infile.txt
grep -E "\[" infile.txt
sed -n '/\[/p' infile.txt
sed -nE '/\[/p' infile.txt
前面的每个命令都会给出以下输出:
[ A ]
[ B ]
[ C
[ D ]
现在我需要指定打印的行应以 开头[
和结尾]
。这个答案到这个问题建议使用正则表达式\[[^\]]*\]
。但是,以下所有命令都不会给出输出(空字符串):
grep "\[[^\]]*\]" infile.txt
grep -E "\[[^\]]*\]" infile.txt
sed -n '/\[[^\]]*\]/p' infile.txt
sed -nE '/\[[^\]]*\]/p' infile.txt
但是以下每个命令...
grep "\[*\]" infile.txt
grep -E "\[*\]" infile.txt
sed -n '/\[*\]/p' infile.txt
sed -nE '/\[*\]/p' infile.txt
...给出所需的输出:
[ A ]
[ B ]
[ D ]
答案1
grep -x '\[.*\]'
应该足以匹配以 ( ) 开头[
和以 ( ) 结尾的行(其间]
有任意数量 ( *
) 的字符 ( ))。.
-x
实际上^
在开头和$
结尾添加了隐式,因此与以下内容相同:
grep '^\[.*\]$'
与 ERE 相同或sed
:
grep -xE '\[.*\]'
grep -E '^\[.*\]$'
sed '/^\[.*\]$/!d'
sed -n '/^\[.*\]$/p'
sed -E '/^\[.*\]$/!d'
sed -En '/^\[.*\]$/p'
你的:
\[[^\]]*\]
匹配 a[
后跟除反斜杠 () 以外的字符,[^\]
后跟任意数量的]
字符,后跟]
。
要匹配 on[
后跟除 之外的任意数量的字符]
,后跟]
,语法是\[[^]]*\]
or\[[^]]*]
因为]
不需要转义,尽管我仍然建议这样做,因为有必要时有正则表达式或 glob 风格。
在[...]
标准 BRE 或 ERE 中(除了awk
),\
并不特殊。不过,有一些正则表达式变体很特殊,所以我仍然建议使用[\\x]
而不是[\x]
例如来匹配\
或x
。
正则表达式有许多不同的风格。那些在https://regexr.com/正如您链接的答案中所示,似乎是(某些版本的)PCRE(与perl兼容的正则表达式),其中一些实现grep
或sed
支持-P
or-R
或-x perl
和 where\
可用于转义]
括号表达式内。
也可以看看:为什么我的正则表达式在 X 中有效但在 Y 中无效?
1 并且目前保证在当前版本的 POSIX 中,尽管这可能会在未来发生变化,因为它无缘无故地阻碍了进展。您会发现,某些实现会sed
忽略该要求,例如,当$POSIXLY_CORRECT
不在 TAB 上匹配的环境中时[\t]
,而不是\
或t
按照 POSIX 要求。要匹配 或\
,t
请使用[\\t]
可移植的。
答案2
让我们解码 RE\[[^\]]*\]
\[
- 文字[
字符[^\]
- 不是\
]
- 文字]
字符*
- 前一项重复零次或多次,即]
零次或多次\]
- 另一个文字]
字符(此处忽略反斜杠)
将其应用到[ A ]
我们可以看到它不匹配。我怀疑你问的问题是为什么[^\]]
它会这样做。否定符号^
有一个特殊情况,当下一个符号是时,]
它会按字面意思处理,否则它总是结构的结尾[...]
。
相反,您可以使用此 RE,\[[^]*]
甚至锚定字符串的正面和背面,^\[.*]$