![编写 bash 代码循环逐行读取具有值的文件,第一个单词作为一行并创建 csv](https://linux22.com/image/203319/%E7%BC%96%E5%86%99%20bash%20%E4%BB%A3%E7%A0%81%E5%BE%AA%E7%8E%AF%E9%80%90%E8%A1%8C%E8%AF%BB%E5%8F%96%E5%85%B7%E6%9C%89%E5%80%BC%E7%9A%84%E6%96%87%E4%BB%B6%EF%BC%8C%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%8D%95%E8%AF%8D%E4%BD%9C%E4%B8%BA%E4%B8%80%E8%A1%8C%E5%B9%B6%E5%88%9B%E5%BB%BA%20csv%20.png)
我有这个样本数据
dn; uid=456456456,cn=users,dc=efsfb,dc=org,dc=co;
objectclass; top;
objectclass; person;
objectclass; organizationalPerson;
objectclass; inetOrgPerson;
uid; 456456456;
givenName; MONICA;
employeeType; CC;
telephoneNumber;456456456;
telexNumber;958;
postalAddress;19770726;
initials; ARBOLEDA;
title; F;
cn; MONICA ARBOLEDA RAIGOSA;
mail; [email protected];
sn; RAIGOSA;
userPassword;;
ibm-entryuuid;;
;;
dn; uid=456456,cn=users,dc=efsfb,dc=org,dc=co;
objectclass; top;
objectclass; person;
objectclass; organizationalPerson;
objectclass; inetOrgPerson;
uid; 456456456;
givenName; SONIA ESPERANZA;
employeeType; CC;
telephoneNumber;456456;
telexNumber;958;
postalAddress;456456;
initials; CASTRO;
employeeNumber;51932787;
title; F;
cn; SONIA ESPERANZA CASTRO TORRES;
mail; [email protected];
sn; TORRES;
userPassword;;
ibm-entryuuid;;
;;
dn; uid=456456,cn=users,dc=efsfb,dc=org,dc=co;
objectclass; top;
objectclass; person;
objectclass; organizationalPerson;
objectclass; inetOrgPerson;
uid; 456456;
userpassword;;
sn; OLIVERA;
givenName; MAURICIO;
cn; MAURICIO REINALES OLIVERA;
employeeType; CC;
mail; [email protected];
telephoneNumber;57383;
telexNumber;958;
postalAddress;19800101;
initials; REINALES;
employeeNumber;456456;
title; M;
ibm-entryuuid;;
;;
dn; uid=CC39681904,cn=users,dc=efsfb,dc=org,dc=co;
objectclass; top;
objectclass; person;
objectclass; organizationalPerson;
objectclass; inetOrgPerson;
uid; CC39681904;
givenName; MARIA DEL PILAR;
employeeType; CC;
telephoneNumber;217001;
telexNumber;958;
postalAddress;456456;
initials; ACUNA;
employeeNumber;456456;
title; F;
cn; MARIA DEL PILAR ACUNA PENA;
mail; [email protected];
sn; PENA;
userPassword;;
ibm-entryuuid;;
;;
你看,不是重复,有的可以有数据,有的没有,但共同点是分隔符“;”前面的第一个单词是一行
我怎样才能像这个示例一样将所有之前的数据转换为 csv
uid employeeType name email
mafsdfsf cc maur mafsdf
mafsdfsf CC5dfgdfg8 monica modfgfdg@g
blabla blabla blabla blabla
我已经用 awk、read IFS、readarray 进行了读取,但我无法达成这笔交易
感谢任何人都可以帮助我
但在本例中所有字段
答案1
使用perl。可能有一个 perl 模块来解析 LDAP 数据,但我没有费心去寻找一个,这很容易做到,不需要任何模块。
顺便说一句,您似乎想要制表符分隔的值,而不是逗号分隔的值。我已相应地命名了该脚本。如果您想要实际的 CSV,那么修改起来很容易(但请记住对每个字段加双引号 -dn
特别是该字段已经包含逗号 - 或者只使用文本::CSV模块生成正确的 CSV 输出)。
$ cat ldap2tsv.pl
#!/usr/bin/perl
use strict;
my @keys = qw(dn uid mail); # array of keys we're interested in
my $match = '^(' . join("|",@keys) . ');'; # turn @keys array into a regex
$match = qr($match); # pre-compile regex for performance
my %data = (); # hash to hold values for each key
print join("\t", @keys), "\n"; # print header line
while(<<>>) {
next unless m/$match/;
my ($key,$val) = split /\s*;\s*/;
$data{$key} = $val;
} continue {
if (m/^;;$/ || eof) {
print join("\t", @data{@keys}), "\n";
%data = ();
};
};
首先创建一个包含我们感兴趣的键名称的数组,然后构建并预编译一个正则表达式以匹配数组中的键名称,并在标题行中打印键。 $match
最终包含正则表达式^(dn|uid|mail);
然后它迭代输入的每一行,忽略与其中一个键不匹配的行。如果当前行匹配,则将其按;
字符(带有可选的前导和/或尾随空格,\s*
)拆分为标量变量$key
和$val
。这些用于将当前行的数据插入到%data
哈希中。
该continue
块在每一行之后执行 - 我在这里使用它来检查一行是否仅包含;;
或我们位于文件末尾。如果是这样,则打印出当前数据行并清除 %data 中的当前值。
示例输出:
$ chmod +x ./ldap2tsv.pl
$ ./ldap2tsv.pl data.txt
dn uid mail
uid=remisor1,cn=users,dc=efsfb,dc=org,dc=co remisor1
uid=paciente1,cn=users,dc=efsfb,dc=org,dc=co paciente1
uid=CC522496sdad48,cn=users,dc=efsfb,dc=org,dc=co CC5dfgdfg8 [email protected]
如果您希望输出在良好对齐的列中,您可以将其通过管道传输到column -t
.但请注意,这会将制表符转换为两个或多个空格。
$ ./ldap2csv.pl data.txt | column -t
dn uid mail
uid=remisor1,cn=users,dc=efsfb,dc=org,dc=co remisor1
uid=paciente1,cn=users,dc=efsfb,dc=org,dc=co paciente1
uid=CC522496sdad48,cn=users,dc=efsfb,dc=org,dc=co CC5dfgdfg8 [email protected]
my @keys = qw(dn uid mail);
将行更改为并针对新数据集运行后my @keys = qw(uid employeeType givenName mail);
,输出现在如下所示:
$ ./ldap2csv.pl data2.txt
uid employeeType givenName mail
456456456 CC MONICA [email protected]
456456456 CC SONIA ESPERANZA [email protected]
456456 CC MAURICIO [email protected]
CC39681904 CC MARIA DEL PILAR [email protected]
或采用良好的格式以供人类阅读column -s $'\t' -t
:
$ ./ldap2csv.pl data2.txt | column -s $'\t' -t
uid employeeType givenName mail
456456456 CC MONICA [email protected]
456456456 CC SONIA ESPERANZA [email protected]
456456 CC MAURICIO [email protected]
CC39681904 CC MARIA DEL PILAR [email protected]
笔记:name
您的数据中没有密钥。有一把givenName
钥匙。我已经用它来代替了。与email
- 没有email
钥匙,但有mail
钥匙相同。