繁体   English   中英

如何使用bash从文件中提取特定行

[英]How to extract specific lines from a file using bash

我正在研究一个脚本,该脚本应从命令结果中提取特定类型的用户及其对应的uidNumber并将其输出到文件中。 示例命令结果为:

dn: uid=test_user_2,ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot
cn: test_user_2
uid: test_user_2
uidNumber: 10000
gidNumber: 400
homeDirectory: /home/test_user_2
userPassword:: e2NyeXB0fSo=

dn: uid=test_user_3,ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot
cn: test_user_3
uid: test_user_3
uidNumber: 500
gidNumber: 400
homeDirectory: /home/test_user_2
userPassword:: e2NyeXB0fSo=

dn: cn=test_group_3,ou=Group,fsFragmentId=Security,fsClusterId=ClusterRoot
cn: test_group_3
gidNumber: 10000
homeDirectory: /home/test_user_3
userPassword:: e2NyeXB0fSo=

我想使用"ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot"uidNumber (10000至60000)来打印所有用户

我已经使用"ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot"提取了行,但是,我不知道如何提取其对应的uidNumber

我使用下面的命令:

$LDAP_command | grep "dn: uid=.*,ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot" > ldapsearch_extracted.txt

预期的输出应如下所示:

dn: uid=test_user_2,ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot
uidNumber: 10000

您可以尝试执行以下命令,

awk '
  /ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot/{print} 
  /uidNumber/{if ($2>=10000 && $2<=60000)print}
' file

sed -n '/^\(dn\|uidNumber\):/H;/^$/ba;$ba;bb;:a;x;/uidNumber: [1-5][0-9]\{4\}\b/p;:b' <file.txt 

dn: uid=test_user_2,ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot
uidNumber: 10000

要么

sed -n '/^\(dn:.*ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot\|uidNumber:\)/H;/^$/ba;$ba;bb;:a;x;/uidNumber: [1-5][0-9]\{4\}/p;:b' <file.txt

说明:

可以写成:

sed -n '
    /^\(dn\|uidNumber\):/H;
    /^$/ba;
    $ba;
    bb;
   :a;
    x;
    /uidNumber: [1-5][0-9]\{4\}\b/p;
   :b
  ' <file.txt 
  • 搜索^dn:^uidNumber ,然后添加以保留空间
  • 在空行^$分支到标签:a
  • 在最后一行标记为:a
  • 分支到标签:b
  • 标签:a
    • 保持空间交换当前模式空间 (空行)
    • 如果uidNumber: [1-5][0-9]\\{4\\} (包括1000059999 ),则打印
  • 标签:b (循环到下一行)

要么

sed -n '
     /^dn:.*ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot/H;
     /^uidNumber:/H;
     /^$/ba;
     $ba;
     bb;
    :a;
     x;
     /uidNumber: [1-5][0-9]\{4\}\b/p;
    :b
   ' <file.txt

在明确条件下:

sed -n '
    /^\(dn\|uidNumber\|gidNumber\):/H;
    /^$/ba;
    $ba;
    bb;
  :a;
    x;
    /uidNumber: [1-5][0-9]\{4\}\b/{
        /ou=People/{
            /fsFragmentId=Security/{
                /fsClusterId=ClusterRoot/{
                    p;
                }
            }
        }
    };
  :b
    ' <file.txt

这将

  • 将dn,uidNumber和gidNumber存储在保留空间中,
  • 在最后一行或空行上,如果uidNumber:[1-5] [0-9] {4}(包括10000至59999),则
    • 如果ou = People,那么
      • 如果fsFragmentId = Security,则
        • 如果fsClusterId = ClusterRoot,则打印。

这样做的主要优点是确保该工作与dn行上的另一个变量顺序相同。

任何时候,只要输入中包含name = value配对,到目前为止,最清晰,最简单和最可扩展的方法是从创建一个包含该映射的数组开始(下面的f[] ),然后您可以按其名称访问值:

$ cat tst.awk
BEGIN { RS=""; FS=OFS="\n"; ORS="\n\n" }
{
    delete f
    for (i=1; i<=NF; i++) {
        name = value = $i
        sub(/:.*/,"",name)
        sub(/^[^:]+:+[[:space:]]*/,"",value)
        f[name] = value
    }
}
(f["dn"] ~ /ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot/) &&
        (f["uidNumber"]+0 >= 10000) && (f["uidNumber"]+0 <= 60000) {
    print p("dn"), p("uidNumber")
}
function p(n) { return n ": " f[n] }

$ awk -f tst.awk file
dn: uid=test_user_2,ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot
uidNumber: 10000

显然,只要遵循上述结构,为实现其他条件和/或按自己喜欢的顺序打印其他字段所要做的其他任何事情都是完全不重要的。

是否要打印gidNumber 只需从以下命令更改打印语句:

    print p("dn"), p("uidNumber")

至:

    print p("dn"), p("uidNumber"), p("gidNumber")

要打印第二条记录吗? 只是改变

(f["dn"] ~ /ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot/) &&
        (f["uidNumber"]+0 >= 10000) && (f["uidNumber"]+0 <= 60000) {

至:

NR==2 {

是否要在cn == uid位置打印记录? 将以上更改为:

f["cn"] == f["uid"] {

是否要打印未填充uidNumber记录? 将以上更改为:

f["uidNumber"] == "" {

您可能想对字段的任何组合进行的操作以及所有其他操作都是显而易见,琐碎且一致的。

上面的代码在下面的文件上运行,您不需要前面的grep或其他任何东西。

$ cat file
dn: uid=test_user_2,ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot
cn: test_user_2
uid: test_user_2
uidNumber: 10000
gidNumber: 400
homeDirectory: /home/test_user_2
userPassword:: e2NyeXB0fSo=

dn: uid=test_user_3,ou=People,fsFragmentId=Security,fsClusterId=ClusterRoot
cn: test_user_3
uid: test_user_3
uidNumber: 500
gidNumber: 400
homeDirectory: /home/test_user_2
userPassword:: e2NyeXB0fSo=

dn: cn=test_group_3,ou=Group,fsFragmentId=Security,fsClusterId=ClusterRoot
cn: test_group_3
gidNumber: 10000
homeDirectory: /home/test_user_3
userPassword:: e2NyeXB0fSo=

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM