Linux:在四个不同的文件中搜索巧合

时间:2014-03-31 10:29:46

标签: bash search

场景:四个文件,每个文件有300行。我想知道只使用bash的所有四个文件中的哪些行(请不要perl / python / ruby​​)

快速示例

$cat bad_domains.urlvoid
a
b
c
d
e

$cat bad_domains.alienvault
f
g
a
c
h

$cat bad_domains.hphosts
i
j
k
a
h

$cat bad_domains.malwaredomain
l
b
m
f
a
j

我只想匹配“a”我试过用这样的东西,但它的速度很慢:

for void in $(cat bad_domains.urlvoid)
do 
    for vault in $(cat bad_domains.alienvault)
    do 
        for hphosts in $(cat bad_domains.hphosts)
        do
            for malwaredomain in $(cat bad_domains.malwaredomain)
            do
                if [ $void == $vault -a $void == $hphosts -a $void == $malwaredomain -a $vault == $hphosts -a $vault == $malwaredomain -a $hphosts == $malwaredomain ]
                then 
                    echo $void
                fi
            done
        done
    done
done

优化代码的任何好建议?我读了一些关于可能有用的二分法搜索的东西。

3 个答案:

答案 0 :(得分:4)

使用comm

comm -12 <(awk 'FNR==NR{a[$0];next} $0 in a' f1 f2) <(awk 'FNR==NR{a[$0];next} $0 in a' f3 f4)
a

使用以下3个步骤:

  1. 从file1和file2获取常用字符串
  2. 从file3和file4获取常用字符串
  3. 从上面的2个步骤中获取共同的字符串,从而得到4组的交集
  4. 编辑:纯awk解决方案:

    awk 'FNR==NR{a[$0];next} $0 in a' <(awk 'FNR==NR{a[$0];next} $0 in a' f1 f2) <(awk 'FNR==NR{a[$0];next} $0 in a' f3 f4)
    

答案 1 :(得分:1)

如果每个文件中的行是唯一的:

cat file1 file2 file3 file4 | sort | uniq -c | grep '^ *4 '

答案 2 :(得分:1)

对于bash 4.x(和ksh93)

创建一个由其中一个文件(主)的行索引的关联数组。

对于其余每个文件,创建一个由文件行索引的第二个数组(工作),然后遍历主文件 数组删除任何带有键的条目,该键也不会出现在工作数组中。

处理后留在master []中的任何键都必须存在于所有文件中。

list=( bad_domains.* )

typeset -A master
while IFS= read -r key ; do master[$key]=1 ; done < "${list[0]}"
unset list[0]

for file in "${list[@]}" ; do
    typeset -A work
    while IFS= read -r key ; do work[$key]=1 ; done < "$file"
    for key in "${!master[@]}" ; do [[ ${work[$key]+set} = set ]] || unset master[$key] ; done
    unset work
done

for key in "${!master[@]}" ; do printf '%s\n' "$key" ; done