使用 awk/sed 根据模式在行中获取特定数据,并将它们排列在 unix 中的列中



我有一个文件如下:

ID: 1  
Name: Admin1  
Class: Administrator  
Class: Leader  
AliasName: User1  
AliasedObject: Administrator,Admin1  
ID: 2  
Name: Admin2  
Class: Administrator  
Class: Leader  
AliasName: User2  
AliasedObject: Administrator,Admin2  
ID: 3  
Name: Admin3  
Class: Administrator  
Class: Leader  
AliasName: User3  
AliasedObject: Administrator,Admin3  

现在我只需要过滤别名和别名对象,如下所示:

AliasName  AliasedObject  
User1      Administrator,Admin1  
User2      Administrator,Admin2  
User3      Administrator,Admin3  

如何在Unix中使用AWK/SED命令执行此操作?

每当你有包含 name=value 对的数据时,最好创建一个 name2value 数组并按字段的名称访问字段,例如:

$ cat tst.awk
BEGIN {
    RS=""; FS="n"; OFS="t"
    numNames = split("AliasName AliasedObject",names,/ /)
    for (i=1; i<=numNames; i++) {
        printf "%s%s", names[i], (i<numNames?OFS:ORS)
    }
}
{
    delete n2v
    for (i=1;i<=NF;i++) {
        name  = gensub(/:.*/,"","",$i)
        value = gensub(/[^:]+:s*/,"","",$i)
        n2v[name] = value
    }
    for (i=1; i<=numNames; i++) {
        printf "%s%s", n2v[names[i]], (i<numNames?OFS:ORS)
    }
}
$ awk -f tst.awk file
AliasName       AliasedObject
User1   Administrator,Admin1
User2   Administrator,Admin2
User3   Administrator,Admin3

这样,如果您想添加稍后要打印的其他字段,您只需将split("AliasName AliasedObject",names,/ /)更改为 split("AliasName AliasedObject Class",names,/ /) 或其他任何内容(但是在数据中具有 2 个不同的字段都名为"Class"将是一个问题,您应该在源头修复,如果数据中确实存在)。

上面使用GNU awk作为几个扩展(delete arraygensub()s),但如果需要的话,可以很容易地调整为适用于任何awk。

虽然以上是一般情况下最好的方法,但对于这种特殊情况,如果您的输入文件值不包含空格,我只会使用 @fedorqui 的简洁解决方案:https://stackoverflow.com/a/29698956/1745001。

假设文件完全像这样,您可以将记录分隔符设置为段落(即RS="",感谢 Ed Morton),然后获取带有一些数据的块:

awk 'BEGIN{RS=""; print "AliasName","AliasedObject"}
     {print $10, $12}' file

测试

$ awk 'BEGIN{RS=""; print "AliasName","AliasedObject"} {print $10,$12}' a
AliasName AliasedObject
User1 Administrator,Admin1
User2 Administrator,Admin2
User3 Administrator,Admin3
sed -n '1 i
AliasName AliasedObject
/^AliasName/ { 
   s/.*:[[:space:]]*//
   N
   s/.AliasedObject:[[:space:]]*/    /p
   }' YourFile
  • 假设文件具有相同的记录结构
  • 加载预期字段行,重新格式化并添加下一个。仅在发生第二次图案修改时打印(安全性低
#!/usr/bin/perl -ln
BEGIN{ $/='';  print "AliasNametAliasedObject";}
%F = m/(?:^|n)(S+):s*(.*)/g;
print "$F{AliasName}   $F{AliasedObject}"

这样,某些字段可以为空、不存在或以不同的顺序写入。

相关内容

  • 没有找到相关文章

最新更新