这是输入的片段:
...
####################
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 3
如果你仅有的想要计算以 '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...