操纵一个巨大的文本文件以获取特定字段的出现

Manipulating a huge text file to fetch occurrences of a particular field

我有一个以下格式的巨大文本文件。我想操纵这个文件来获取部门字段的出现次数。每个部分都有一个名为 department: 的字段 由于我的程序,我需要 Expected output 部分中提到的 CSV 文件。如果解决方案使用 sed 或 head/tail 或 awk,我将不胜感激。文件真的很大。我有大约 50,000 多行代码。所以非常感谢一个有效的方法。

Input format:


# Person1 Perosn2, AADDC Users, dummydata.somecompany.com
dn: CN=Person1 Perosn2,OU=AADDC Users,DC=dummydata,DC=somecompany,DC=com
objectClass: top
department: 234ABC
name: Person1 Perosn2
objectGUID:: MbCDVZpKbEWRxDUA5iN5IA==
userPrincipalName: abcdef@dummydata.somecompany.com
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=dummydata,DC=somecompany
 ,DC=com
dSCorePropagationData: 16010101000000.0Z
lastLogonTimestamp: 132173602593105876
preferredLanguage: en-US
msDS-AzureADMailNickname: abcdef


# Person1 Perosn2, AADDC Users, dummydata.somecompany.com
dn: CN=Person1 Perosn2,OU=AADDC Users,DC=dummydata,DC=somecompany,DC=com
objectClass: top
department: 234ABC
name: Person1 Perosn2
objectGUID:: MbCDVZpKbEWRxDUA5iN5IA==
userPrincipalName: abcdef@dummydata.somecompany.com
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=dummydata,DC=somecompany
 ,DC=com
dSCorePropagationData: 16010101000000.0Z
lastLogonTimestamp: 132173602593105876
preferredLanguage: en-US
msDS-AzureADMailNickname: abcdef

# Person3 Perosn4, AADDC Users, dummydata.somecompany.com
dn: CN=Person1 Perosn2,OU=AADDC Users,DC=dummydata,DC=somecompany,DC=com
objectClass: top
department: XYZ012
name: Person1 Perosn2
objectGUID:: MbCDVZpKbEWRxDUA5iN5IA==
userPrincipalName: abcdef@dummydata.somecompany.com
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=dummydata,DC=somecompany
 ,DC=com
dSCorePropagationData: 16010101000000.0Z
lastLogonTimestamp: 132173602593105876
preferredLanguage: en-US
msDS-AzureADMailNickname: abcdef


Expected output

234ABC,2
XYZ012,1

我做了什么:

我用这个命令来grep文件。 grep '^department: *' file.txt

但我不确定是否有办法使用 sed、grep 等单个命令获得预期的输出

能否请您尝试以下。

awk '
BEGIN{
  OFS=","
}
{
  gsub(/\r/,"")
}
/department:/{
  string=$NF
  sub(/ +$/,"",string)
  if(!a[string]++){
    b[++count]=string
  }
  ++val[string]
}
END{
  for(i=1;i<=count;i++){
    print b[i],val[b[i]]
  }
}
'  Input_file

这可能适合您 (GNU sed):

sed -En 's/^department: //;T;G;/^(\S+\n)(\S+\n)*/!P;h' file

忽略不以 department: 开头的行。将行的剩余部分存储在保留 space 中,如果它对于保留 space 中的其他行是唯一的,则打印它。