场景:四个文件,每个文件有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
优化代码的任何好建议?我读了一些关于可能有用的二分法搜索的东西。
答案 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个步骤:
编辑:纯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