Unix命令通过根据条件

时间:2015-12-15 17:56:35

标签: linux unix join awk sed

我有2个文件。基本上我想匹配文件1中的列名与文件2中列出的列名。结果输出文件应该包含与文件2匹配的列的数据和文件2中剩余列名的Null值。

示例

文件1

Name|Phone_Number|Location|Email
Jim|032131|xyz|xyz@qqq.com
Tim|037903|zzz|zzz@qqq.com
Pim|039141|xxz|xxz@qqq.com

文件2

Location
Name
Age

基于这两个文件,我想创建一个新文件,其中包含以下格式的数据:

输出:

    

Location|Name|Age
    xyz|Jim|Null
    zzz|Tim|Null
    xxz|Pim|Null

有没有办法使用joinawksed获得此结果。我尝试了加入,但无法使其正常工作。

2 个答案:

答案 0 :(得分:2)

$ cat tst.awk
BEGIN { FS=OFS="|" }
NR==FNR { names[++numNames] = $0; next }
FNR==1 {
    for (nameNr=1;nameNr<=numNames;nameNr++) {
        name = names[nameNr]
        printf "%s%s", name, (nameNr<numNames?OFS:ORS)
    }
    for (i=1;i<=NF;i++) {
        name2fldNr[$i] = i
    }
    next
}
{
    for (nameNr=1;nameNr<=numNames;nameNr++) {
        name = names[nameNr]
        fldNr = name2fldNr[name]
        printf "%s%s", (fldNr?$fldNr:"Null"), (nameNr<numNames?OFS:ORS)
    }
}

$ awk -f tst.awk file2 file1
Location|Name|Age
xyz|Jim|Null
zzz|Tim|Null
xxz|Pim|Null

获取由Arnold Robbins撰写的Effective Awk Programming,4th Edition。

答案 1 :(得分:0)

我建议使用csvcut,它是CSVKit(https://csvkit.readthedocs.org)的一部分,沿着以下几行:

#!/bin/bash
HEADERS=File2
PSV=File1

headers=$(tr '\n' , < "$HEADERS" | sed 's/,$//' )

awk '-F|' '
    BEGIN {OFS=FS}
    NR==1 {print $0,"Age"; next}
    {print $0, "Null"}' "$PSV" ) |\
  csvcut "-d|" -c "$headers"

我意识到这可能不完全令人满意,但csvcut目前没有处理缺失列或将缺失数据转换为指定值的选项。