Bash의 첫 번째 필드로 정렬된 행 수를 계산하는 방법

Bash의 첫 번째 필드로 정렬된 행 수를 계산하는 방법

다음은 입력의 일부입니다.

...
####################
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...
...

이것은 내가 필요한 출력의 일부입니다.

Bala Bela;XXXXXX12345;XXXXXX12345678;A
4
Ize Jova;XXXXXX12345;XXXXXX12345;A
3

따라서 "SERVER"로 시작하는 줄이 특정 사용자에게 전송되었는지 확인하려면 입력 출력이 필요합니다(예: "Bala Bela;XXXXXX12345;XXXXXX12345678;A"). Bash에서 어떻게 할 수 있나요?

답변1

{
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

Perl의 단일 코드 라인에도 동일하게 적용됩니다.

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

골프도 치고

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

답변2

이 버전은 줄의 정규식과 일치하지 않는 모든 줄을 계산합니다 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"
    }
}

산출:

바라벨라;XXXXXX12345;XXXXXX12345678;A
4
이제 조바;XXXXXX12345;XXXXXX12345;A

만약 너라면오직'SERVER'로 시작하는 줄 수를 계산하려면 다음을 수행하세요.

#! /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"
    }
}

답변3

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

산출:

Bala Bela;XXXXXX12345;XXXXXX12345678;A
4
Ize Jova;XXXXXX12345;XXXXXX12345;A
3

접두사 계산이 정상인 경우:

sed -n ':a /^SERVER/{g;p;ba}; h' file |uniq -c

산출:

  4 Bala Bela;XXXXXX12345;XXXXXX12345678;A
  3 Ize Jova;XXXXXX12345;XXXXXX12345;A

답변4

따라서 출력이 이미 각 "버킷" 내에서 정렬되어 있는 경우 uniq를 직접 적용하고 처음 N 문자만 확인할 수 있습니다.

cat x | uniq -c -w6

여기서 N==6은 SERVER가 줄 시작 부분의 6자로 구성되기 때문입니다. 다음과 같은 결과가 출력됩니다(원하는 것과 약간 다름).

  1 ####################
  1 Bala Bela;XXXXXX12345;XXXXXX12345678;A
  4 SERVER345Z3.DOMAIN.com0
  1 ssh-dss ...pubkeyhere...
  1 ####################
  1 Ize Jova;XXXXXX12345;XXXXXX12345;A
  3 SERVER342Z3.DOMAIN.com0
  1 ssh-rsa ...pubkeyhere...

관련 정보