我需要从 LDAP 基本转储文件中提取大约 6 个项目
fullName:
uid:
email:
...
搜索需要冒号,主要是因为 uid 出现在文件中的多个位置,但 uid: 是我需要的。我尝试转义冒号,但我使用的任何组合都可能会查出第一个搜索项,但不会查出第二个搜索项。然后我还有三四个项目要添加到列表中。
现有输出:
gw1:~ # cat dump2.txt|awk "/email:/" && "/fullName:/"
-bash: /fullName:/: No such file or directory
gw1:~ # cat dump2.txt|grep -e "email:" -e "fullName:"
fullName: LDAP Proxy2
fullName: Student Email Administrator
fullName: Richard C. Holly
fullName: Jene E. Brown
预期输出:
gw1:~ # cat dump2.txt|awk "/email\:/" print{','} && "/fullName\:/" print{','} && "/gid\:/"
email: [email protected] , fullName: LDAP Proxy2, gui: 987
注意 csv 格式。
答案1
让我们从一个示例输入文件开始:
$ cat dump.txt
some: other
email: [email protected]
fullName: LDAP Proxy2
gui: 987
other: thing
要提取所需的行并将其重新格式化为 CSV:
$ awk '/email:|fullName:|gui:/{s=s", "$0} END{print substr(s,3)}' dump.txt
email: [email protected], fullName: LDAP Proxy2, gui: 987
怎么运行的:
/email:|fullName:|gui:/{s=s", "$0}
这是一个条件,后跟一个语句。条件是正则表达式
/email:|fullName:|gui:/
,仅对于包含您要查找的字符串之一的行才成立。在正则表达式中,该|
符号表示逻辑或。如果条件为真,则执行该语句。该语句会导致将逗号、空格、当前行附加到变量
s
。awk
隐式循环文件中的所有行,并对每一行执行上述操作。END{print substr(s,3)}
当我们读完输入文件后,我们想要打印除前两个字符之外的所有字符
s
。前两个字符是“,”,这是多余的。该函数substr
用于删除它们。
样本输出
使用您提供的文件paste.ee
并选择您在评论中指定的字段(“mail:”、“fullName”和“uid”),我得到:
$ awk '/mail:|fullName:|uid:/{s=s", "$0} END{print substr(s,3)}' dump.txt
mail: [email protected], uid: pgroce, fullName: Patti K. Groce
所有字段均已找到。
输入空白字段
根据评论,考虑dump3.txt
最后有一些空白条目:
$ cat dump3.txt
other: thing
mail: [email protected]
uid: pgroce
fullName: Patti K. Groce
mail:
mail:
Other: Thing
mail:
$ awk '/mail:|fullName:|uid:/{s=s", "$0} END{print substr(s,3)}' dump3.txt
mail: [email protected], uid: pgroce, fullName: Patti K. Groce, mail:, mail:, mail:
按照您的要求,空条目将打印为空条目。
答案2
您可以将整个文件解析为 Perl 哈希并打印出所需字段(在文件名后面作为输入参数给出):
perl -nle '
BEGIN{
$input_file = shift;
$required_fields = shift
}
my ($field,$val) = split/:/;
next unless defined $field; #Skip lines with no field names
$fields{$field} = $val;
END{
print join ",",@fields{split/,/,$required_fields}
}' your_file 'email,fullName,gui'