Cách đếm hàng được sắp xếp theo trường đầu tiên trong bash


9

Đây là đoạn trích từ 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...
...

Và đây là một đoạn trích từ OUTPUT mà tôi cần:

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

Vì vậy, tôi cần một OUTPUT từ INPUT, để tôi có thể thấy có bao nhiêu hàng bắt đầu bằng "SERVER" được chuyển đến người dùng đã cho (ví dụ: "Bala bela; XXXXXX12345; XXXXXX12345678; A"). Làm thế nào tôi có thể làm điều này trong bash?


Bạn có yêu cầu điều này phải là Bash độc lập hay các công cụ khác được chấp nhận (grep, awk, perl ...)?
ire_and_curses

tôi sẽ giả định (và đã làm như vậy :) rằng, trừ khi có quy định rõ ràng khác, một câu hỏi bash script cho phép tất cả các công cụ tiêu chuẩn như grep, awk, sed, perl và tất cả phần còn lại.
cas

Câu trả lời:


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

Tương tự trong 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

và chơi gôn

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

ồ perl thật tuyệt vời: D
gasko peter

5

Phiên bản này đếm tất cả các hàng không khớp với biểu thức chính quy trong grepdòng.

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

Đầu ra:

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

Nếu bạn chỉ muốn đếm các dòng bắt đầu bằng 'SERVER', thì:

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

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

Đầu ra:

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

Nếu số tiền tố là ok:

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

Đầu ra:

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

4

Một awkthay thế:

/^#{15,}/ {           # if line starts with 15 or more number signs
  if(k) {             # if any key found
    print k RS n      # print it and occurrences of SERVER
    n=0
  }
  getline             # key is on the next line
  k = $0
  next                # move to next record
} 

/SERVER/ { n++ }      # count occurrences of SERVER
END { print k RS n }  # print last record

Tất cả trên một dòng:

awk '/^#{15,}/ { if(n>0) { print k RS n; n=0 }; getline; k = $0; next } /SERVER/ { n++ } END { print k RS n }'

2

Vì vậy, nếu đầu ra đã được sắp xếp trong mỗi "nhóm", bạn có thể trực tiếp áp dụng uniq bằng cách chỉ kiểm tra N ký tự đầu tiên:

cat x | uniq -c -w6

Đây là N == 6 vì SERVER bao gồm 6 ký tự từ đầu dòng. Bạn sẽ kết thúc với đầu ra này (khác một chút so với đầu ra cần thiết của bạn):

  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...
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.