使用Unix根据另一个文件中存在的值从一个文件中过滤记录

时间:2019-04-13 19:27:20

标签: shell unix

我有一个输入csv文件Input feed

PK,Col1,Col2,Col3,Col4,Col5    
A,1,2,3,4,5
B,1,A,B,C,D
C,1,2,3,4
D,2,1,2,3
E,5,1,1,1
F,8,1,1,1

有一个包含主键的输入文件会生成一个输出错误的csv文件

Error File

    Pk,Error_Reason   
    D,Failure
    E, Failure
    F, Failure

我想从输入文件中提取所有记录,并将其保存到错误文件中有主键条目的新文件中。

基本上,我的新文件应如下所示:

New Input feed

PK,Col1,Col2,Col3,Col4,Col5    
D,2,1,2,3
E,5,1,1,1
F,8,1,1,1

我是Unix的初学者,我已经尝试过Awk命令。

我尝试过的方法是,将所有主键值放入文件中。

akw -F“,”'{print $ 2}'error.csv >> error_pk.csv

现在,我需要从input.csv中过滤掉error.pk中存在的所有主键值的记录

3 个答案:

答案 0 :(得分:1)

您可以使用join

首先从第二个文件中删除逗号后的所有内容
从两个文件的第一个字段加入

cat <<EOF >file1
PK,Col1,Col2,Col3,Col4,Col5    
A,1,2,3,4,5
B,1,A,B,C,D
C,1,2,3,4
D,2,1,2,3
E,5,1,1,1
F,8,1,1,1
EOF

cat <<EOF >file2
PK,Error_Reason   
D,Failure
E,Failure
F,Failure
EOF

join -t, -11 -21 <(sort -k1 file1) <(cut -d, -f1 file2 | sort -k1)

如果您需要根据file1对文件进行排序,则可以对第一个文件中的行进行编号,合并文件,使用行号重新排序,然后从输出中删除数字:

join -t, -12 -21 <(nl -w1 -s, file1 | sort -t, -k2) <(cut -d, -f1 file2 | sort -k1) |
sort -t, -k2 | cut -d, -f1,3-

答案 1 :(得分:1)

使用awk。由于错误文件中有前导空格,因此需要首先对其进行修整,为此,我使用了sub。然后,由于第一列的标题不同,(PK与Pk)需要分别用FNR==1处理:

$ awk -F, '                      # set separator
NR==FNR {                        # process the first file
    sub(/^ */,"")                # trim leading space
    a[$1]                        # hash the first column
    next  
}
FNR==1 || ($1 in a)' error input # output tthe header record and if match hashed

输出:

PK,Col1,Col2,Col3,Col4,Col5    
D,2,1,2,3
E,5,1,1,1
F,8,1,1,1

答案 2 :(得分:1)

您可以对包含搜索项的文件使用grep -f。切断,

grep -Ef <(sed -r 's/([^,]*).*/^\1,/' file2) file1

要在输出中显示标题时,