比较两个文件中的值

时间:2012-05-25 12:51:46

标签: bash shell

我正在比较两个文件,每个文件有一列和n行。

档案1


亚历克斯
罗宾

文件2

艾伦
亚历克斯
亚伦
拉尔夫
罗宾

如果文件1中存在文件1的数据,则应在选项卡分隔文件中返回1或0,否则为

像这样的东西

vincy 0
alex 1
罗宾1

我正在做的是

#!/bin/bash
for i in `cat file1 `
do
cat file2 | awk '{ if ($1=="'$i'") print 1 ; else print 0 }'>>binary
done

上面的代码没有给我输出我想要的输出。

请看看并建议更正。

谢谢

6 个答案:

答案 0 :(得分:2)

简单的awk解决方案:

awk 'NR==FNR{ seen[$0]=1 } NR!=FNR{ print $0 " " seen[$0] + 0}' file2 file1

一个简单的解释:对于file2中的行,NR == FNR,所以执行第一个动作,我们只记录已经看到一行。在file1中,执行第二个操作并打印行,后跟一个空格,后跟一个“0”或“1”,具体取决于是否在file2中看到该行。

答案 1 :(得分:2)

AWK 喜欢来做这件事。

awk 'FNR == NR {a[tolower($1)]; next} {f = 0; if (tolower($1) in a) {f = 1}; print $1, f}' file2 file1

在参数列表中交换file2和file1的位置,使file1成为字典而不是file2。

FNR(当前文件中的记录号)和NR(到目前为止所有记录的记录号)相等时,第一个文件是正在处理的文件。简单地引用数组元素就可以实现它。这会设置字典。 next指令读取下一条记录。

FNRNR不相等后,正在处理后续文件,并在字典数组中查找其数据。

答案 2 :(得分:1)

以下代码应该这样做。

仔细查看BEGINEND部分。

#!/bin/bash
rm -f binary
for i in $(cat file1); do
     awk 'BEGIN {isthere=0;} { if ($1=="'$i'") isthere=1;} END { print "'$i'",isthere}' < file2 >> binary
done

答案 3 :(得分:1)

存在comm命令为您进行此类比较。

以下方法只进行一次传递并可以很好地扩展到非常大的输入列表:

#!/bin/bash
while read; do
        if [[ $REPLY = $'\t'* ]] ; then
                printf "%s\t0\n" "${REPLY#?}"
        else
                printf "%s\t1\n" "${REPLY}"
        fi
done < <(comm -2 <(tr '[A-Z]' '[a-z]' <file1 | sort) <(tr '[A-Z]' '[a-z]' <file2 | sort))

另请参阅BashFAQ #36,它是直接在线的。

答案 4 :(得分:1)

有几种不错的方法。您只需使用line-by-line set math

即可
{
    grep -xF -f file1 file2 | sed $'s/$/\t1/'
    grep -vxF -f file1 file2 | sed $'s/$/\t0/'
} > somefile.txt

另一种方法是简单地组合文件并使用uniq -c,然后只需将数据列与awk交换:

sort file1 file2 | uniq -c | awk '{ print $2"\t"$1 }'

答案 5 :(得分:1)

另一种解决方案,如果你安装了python。 如果您熟悉Python并且对该解决方案感兴趣,则只需要进行一些格式化。

#/bin/python
f1 = open('file1').readlines()
f2 = open('file2').readlines()
f1_in_f2 = [int(x in f2) for x in f1]
for n,c in zip(f1, f1_in_f2):
    print n,c