如何计算bash中第一个字段排序的行

gas*_*ter 9 bash text-processing

这是 INPUT 的一个片段:

...
####################
Bala Bela;XXXXXX12345;XXXXXX12345678;A
SERVER345Z3.DOMAIN.com0
SERVER346Z3.DOMAIN.com0
SERVER347Z3.DOMAIN.com0
SERVER348Z3.DOMAIN.com0
ssh-dss ...pubkeyhere...
####################
Ize Jova;XXXXXX12345;XXXXXX12345;A
SERVER342Z3.DOMAIN.com0
SERVER343Z3.DOMAIN.com0
SERVER345Z3.DOMAIN.com0
ssh-rsa ...pubkeyhere...
...
Run Code Online (Sandbox Code Playgroud)

这是我需要的 OUTPUT 片段:

Bala Bela;XXXXXX12345;XXXXXX12345678;A
4
Ize Jova;XXXXXX12345;XXXXXX12345;A
3
Run Code Online (Sandbox Code Playgroud)

所以我需要来自 INPUT 的 OUTPUT,以便我可以看到有多少行以“SERVER”开头给给定用户(例如:“Bala Bela;XXXXXX12345;XXXXXX12345678;A”)。我怎样才能在 bash 中做到这一点?

Nah*_*eul 6

{
i=0
while IFS= read -r line; do
  case "$line" in
    ssh*|'##'*)
      ;;
    SERVER*)
      ((++i))
      ;;
    *)
      if ((i>0)); then echo $i;i=0; fi
      echo "$line"
      ;;
  esac
done
if ((i>0)); then echo $i;i=0; fi
} <inputfile >outputfile
Run Code Online (Sandbox Code Playgroud)

在 perl one-liner 中相同

perl -nle '
  BEGIN{$i=0}
  next if/^(ssh|##)/;
  if(/^SERVER/){++$i;next}
  print$i if$i>0;
  $i=0;
  print;
  END{print$i if$i>0}' inputfile >outputfile
Run Code Online (Sandbox Code Playgroud)

和打高尔夫球

perl -nle's/^(ssh|##|(SERVER))/$2&&$i++/e&&next;$i&&print$i;$i=!print}{$i&&print$i' inputfile >outputfile
Run Code Online (Sandbox Code Playgroud)


cas*_*cas 5

此版本计算与行中正则表达式不匹配的所有行grep

#! /usr/bin/perl 

# set the Input Record Separator (man perlvar for details)
$/ = '####################';

while(<>) {
    # split the rows into an array
    my @rows = split "\n";

    # get rid of the elements we're not interested in
    @rows = grep {!/^#######|^ssh-|^$/} @rows;

    # first row of array is the title, and "scalar @rows"
    # is the number of entries, so subtract 1.
    if (scalar(@rows) gt 1) {
      print "$rows[0]\n", scalar @rows -1, "\n"
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

巴拉贝拉;XXXXXX12345;XXXXXX12345678;A
4
伊泽乔瓦;XXXXXX12345;XXXXXX12345;A
3

如果你只是想用计数“服务器”,然后开始的行:

#! /usr/bin/perl 

# set the Input Record Separator (man perlvar for details)
$/ = '####################';

while(<>) {
    # split the rows into an array
    my @rows = split "\n";

    # $rows[0] will be same as $/ or '', so get title from $rows[1]
    my $title = $rows[1];

    my $count = grep { /^SERVER/} @rows;

    if ($count gt 0) {
      print "$title\n$count\n"
    }
}
Run Code Online (Sandbox Code Playgroud)


Pet*_*r.O 5

sed -n ':a /^SERVER/{g;p;ba}; h' file | uniq -c | 
  sed -r 's/^ +([0-9]) (.*)/\2\n\1/'
Run Code Online (Sandbox Code Playgroud)

输出:

Bala Bela;XXXXXX12345;XXXXXX12345678;A
4
Ize Jova;XXXXXX12345;XXXXXX12345;A
3
Run Code Online (Sandbox Code Playgroud)

如果前缀计数没问题:

sed -n ':a /^SERVER/{g;p;ba}; h' file |uniq -c
Run Code Online (Sandbox Code Playgroud)

输出:

  4 Bala Bela;XXXXXX12345;XXXXXX12345678;A
  3 Ize Jova;XXXXXX12345;XXXXXX12345;A
Run Code Online (Sandbox Code Playgroud)