Shell

編寫bash程式碼逐行循環具有值的文件,將第一個單詞作為一行並創建csv

  • March 9, 2022

我有這個樣本數據

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; fghfghfgh@gmail.com;
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; fghfh@gmail.com;
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; mfghfh@gmail.com;
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; mafsdfsf@gmail.com;
sn; PENA;
userPassword;;
ibm-entryuuid;;
;;

如果你看,不是重複,有些可以有數據有些沒有,但常見的是分隔符“;”之前的第一個單詞 是一排

我如何將所有之前的數據轉換為 csv 像這個範例

uid       employeeType            name                  email
mafsdfsf    cc                      maur                  mafsdf 
mafsdfsf   CC5dfgdfg8               monica               modfgfdg@g
blabla       blabla                 blabla              blabla

我讀過 awk,讀過 IFS,readarray,但我不能做這筆交易

感謝任何人都可以幫助我

但在這種情況下,所有領域

使用 perl。可能有一個 perl 模組來解析 LDAP 數據,但我沒有費心去尋找一個,這很容易在沒有任何模組的情況下完成。

順便說一句,您似乎想要 TAB 分隔值,而不是 COMMA 分隔。我已經相應地命名了腳本。如果您想要實際的 CSV,那麼修改起來很容易(但請記住對每個欄位進行雙引號 -dn特別是該欄位已經包含逗號 - 或者只使用Text::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      modfgfdg@gmail.com

如果您希望輸出在對齊良好的列中,您可以將其通過管道傳輸到column -t. 但是請注意,這會將 TAB 字元轉換為兩個或多個空格。

$ ./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  modfgfdg@gmail.com

my @keys = qw(dn uid mail);行更改為my @keys = qw(uid employeeType givenName mail);並針對新數據集執行後,輸出現在如下所示:

$ ./ldap2csv.pl data2.txt 
uid     employeeType    givenName       mail
456456456       CC      MONICA  fghfghfgh@gmail.com
456456456       CC      SONIA ESPERANZA fghfh@gmail.com
456456  CC      MAURICIO        mfghfh@gmail.com
CC39681904      CC      MARIA DEL PILAR mafsdfsf@gmail.com

或很好地格式化為人類可讀性column -s $'\t' -t

$ ./ldap2csv.pl data2.txt | column -s $'\t' -t
uid         employeeType  givenName        mail
456456456   CC            MONICA           fghfghfgh@gmail.com
456456456   CC            SONIA ESPERANZA  fghfh@gmail.com
456456      CC            MAURICIO         mfghfh@gmail.com
CC39681904  CC            MARIA DEL PILAR  mafsdfsf@gmail.com

**注意:**您的數據中沒有name鍵。有一把givenName鑰匙。我用過那個。與email- 沒有email鑰匙,但有mail鑰匙相同。

引用自:https://unix.stackexchange.com/questions/693656