我正在比较两个文件,每个文件有一列和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
上面的代码没有给我输出我想要的输出。
请看看并建议更正。
谢谢
答案 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
指令读取下一条记录。
FNR
和NR
不相等后,正在处理后续文件,并在字典数组中查找其数据。
答案 2 :(得分:1)
以下代码应该这样做。
仔细查看BEGIN
和END
部分。
#!/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