使用特定字符的一个实例对所有行进行 Grep

Tor*_*ten 5 grep sed awk text-processing

我想用一行中只有一个“#”来grep所有行。

例子:

xxx#aaa#iiiii
xxxxxxxxx#aaa
#xxx#bbb#111#yy
xxxxxxxxxxxxxxxx#
xxx#x
#x#v#e#
Run Code Online (Sandbox Code Playgroud)

应该给出这个输出

xxxxxxxxx#aaa
xxxxxxxxxxxxxxxx#
xxx#x
Run Code Online (Sandbox Code Playgroud)

Arc*_*mar 22

尝试

grep '^[^#]*#[^#]*$' file
Run Code Online (Sandbox Code Playgroud)

在哪里

^      ; begin of line
[^#]*  ; any number of char ? #
#      ; #
[^#]*  ; any number of char ? #
$      ; end of line
Run Code Online (Sandbox Code Playgroud)

正如建议的那样,您可以在整行中使用 grep

grep -x '[^#]*#[^#]*'
Run Code Online (Sandbox Code Playgroud)

  • 没有行首/行尾锚点的相同模式。
  • -x 要 grep 整行,请参阅 man grep
-x, --line-regexp
   Select  only  those  matches  that  exactly  match  the  whole line.  For a regular
   expression pattern, this is like parenthesizing the pattern and then surrounding it
   with ^ and $.
Run Code Online (Sandbox Code Playgroud)


αғs*_*нιη 16

使用awk

awk -F'#' 'NF==2' infile
Run Code Online (Sandbox Code Playgroud)

基于#字段分隔符,如果一行中的字段数正好是两个字段,则将打印出来。请注意,例如#xx#什至#被视为两个字段等。


Ste*_*ton 9

两次调用grep: 选择任何至少有一个 的行#,然后删除那些至少有两个的行:

grep '#' filename | grep -v '#.*#'
Run Code Online (Sandbox Code Playgroud)


fpm*_*phy 5

使用 GNU grep:

$ grep -P '^(?!(?:.*#){2}).*#' infile
xxxxxxxxx#aaa
xxxxxxxxxxxxxxxx#
xxx#x
$
Run Code Online (Sandbox Code Playgroud)

-P 选项表示使用 PCRE(Perl 兼容正则表达式)正则表达式。请参阅https://www.pcre.org。PCRE 是 ERE(扩展正则表达式)的扩展,最初引入到 Perl 中,后来被许多命令、实用程序、应用程序和编程语言采用。

如果 GNU grep 在您的平台上不可用,您可以安装它,它是许多平台上可用的软件包pcregrep的一部分。pcre-tools

这个特定 PCRE 正则表达式的通用形式是:

^(?!(?:.*PATTERN){2}).*PATTERN
Run Code Online (Sandbox Code Playgroud)

其中PATTERN代表您希望在 grep 字符串中出现一次且仅出现一次的模式。在我们的例子中,模式是#

  • ^- 字符串的开头
  • (?!(?:.*PATTERN){2})- 如果有两个 ( ) 连续出现,则否定前瞻会导致紧邻当前位置(即字符串开头)右侧的匹配失败{2}
    • .*- 0个或多个字符
    • PATTERN- 模式
  • .*- 0个或多个字符
  • PATTERN- 模式

  • 你愿意解释一下正则表达式吗? (7认同)