在第一列匹配后从2个文件中删除行

时间:2018-02-07 06:46:18

标签: unix awk sed

我有两个文件file1& file2,我想根据第一列删除不匹配的行,即ID

File1中

ID,NAME,ADDRESS
11,PP,LONDON
12,SS,BERLIN
13,QQ,FRANCE
14,LL,JAPAN

文件2

ID,NAME,ADDRESS
11,PP,LONDON
12,SS,BERLIN
13,QQ,FRANCE
16,WW,DUBAI

我想删除行

From File1
14,LL,JAPAN 

From File2
16,WW,DUBAI

使用DIFF命令我能够存档但我想删除这些行。

同样使用AWK我可以使用以下命令将这些行重定向到另一个文件。

awk 'FNR==NR{a[$1];next};!($1 in a)' File1 File2 > File3

但不知道如何删除。

我们可以这样做吗?

Using sed -id 's/AWK OUTPUT/g' File1

由于

3 个答案:

答案 0 :(得分:2)

您甚至无需使用awk进行此操作grep绰绰有余:

$ more file1 file2
::::::::::::::
file1
::::::::::::::
ID,NAME,ADDRESS
11,PP,LONDON
12,SS,BERLIN
13,QQ,FRANCE
14,LL,JAPAN
::::::::::::::
file2
::::::::::::::
ID,NAME,ADDRESS
11,PP,LONDON
12,SS,BERLIN
13,QQ,FRANCE
16,WW,DUBAI

$ grep -f <(grep -oP '^[^,]*,' file1) file2 > new_file2; grep -f <(grep -oP '^[^,]*,' file2) file1 > new_file1

$ more new_file*
::::::::::::::
new_file1
::::::::::::::
ID,NAME,ADDRESS
11,PP,LONDON
12,SS,BERLIN
13,QQ,FRANCE
::::::::::::::
new_file2
::::::::::::::
ID,NAME,ADDRESS
11,PP,LONDON
12,SS,BERLIN
13,QQ,FRANCE

<强>说明

你使用grep -oP从每一行中用逗号提取id并再次调用grep并传递模式列表,好像它是一个文件来分析第二个文件,这将只打印匹配的行,你对其他文件做同样的事。

但是,在流程结束时两个文件都是相同的,因此您无需运行grep -f <(grep -oP '^[^,]*,' file2) file1 > new_file1

另一种处理方式是使用以下命令:

$ grep -F -f <(paste -d'\n' <(cut -d',' -f1 file1 | sort -n) <(cut -d',' -f1 file2 | sort -n) | uniq -D | uniq) file1 > new_file1

$ more new_file1
ID,NAME,ADDRESS
11,PP,LONDON
12,SS,BERLIN
13,QQ,FRANCE

答案 1 :(得分:2)

使用tee命令回答:

请注意我已删除 PATH 标志

!

您可以使用原来的awk命令进行一些小改动

1)删除 awk 'FNR==NR{a[$1];next};($1 in a)' File1 File2 | tee File1

2)使用!将awk结果发送到文件 - 使用tee command仅在|之前的命令结束时执行下一个命令

答案 2 :(得分:1)

使用GNU awk&#39; inplace edit(请参阅版本讨论链接):

$ awk -i inplace '            # inplace edit modifies the original files
BEGIN { FS="," }              # comma delimited files
NR==FNR {                     # first file, hash all records and set value to 1
    a[$1]++
}
($1 in a) && a[$1]==ARGIND {  # if index in a and it has been in each file read
    a[$1]++                   # ... increase count 
    print                     # ... and print to current file
}' file1 file2 file1

结果:

$ cat file1
ID,NAME,ADDRESS
11,PP,LONDON
12,SS,BERLIN
13,QQ,FRANCE
$ cat file2
ID,NAME,ADDRESS
11,PP,LONDON
12,SS,BERLIN
13,QQ,FRANCE

注意:就地编辑会修改原始文件,所以要小心。如果您想在不使用原始文件副本的情况下对其进行测试,则可以移除-i inplace并将print替换为print FILENAME, $0

处理第一个文件时,每个id都会被散列到a并且其值增加到1,因此会输出到file1,使其保持原始格式(如果没有重复的ID)。对于a中找到的第二个文件ID,会增加并打印回file2,并且适用于第二次处理的file1