牛年大吉!
场景
批量下载文件时,发现部分文件下载失败(大约10%)
手头上有原始文件地址、已下载文件名,需要找到下载失败的地址。
探索
A
首先是找到的awk差集命令1
awk 'NR==FNR{ a[$1]=$1 } NR>FNR{ if(a[$1] == ""){ print $1}}' aaa.txt bbb.txt
思路是用数组存文件1
的行数据,再用文件2
搜是否存在
优点是效率高命令简洁,缺点是扩展麻烦,文件2
需要做预处理,要把地址里的文件名单独提取一列。
B
然后找到的是awk对比脚本1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16/bin/bash
file1="aaa.txt"
file2="bbb.txt"
lines=`cat $file1 | wc -l` + 1
for ((i=1;i<=$lines;i++))
do
line1=`awk 'NR=='$i'{print $0}' $file1`
line2=`awk 'NR=='$i'{print $0}' $file2`
if [[ $line1 != $line2 ]]
then
echo "line $i is not equal"
fi
done
优点扩展性更好,缺点是每次循环都需要定位行,性能浪费严重。
脚本
基于B魔改了一个脚本:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22!/bin/bash
文件地址
file1="aaa.txt"
已下载文件名
file2="bbb.txt"
lines=`cat $file1 | wc -l`+1
for ((i=1;i<=$lines;i++))
do
定位当前循环对比行
line1=`awk 'NR=='$i'{print $0}' $file1`
摘出文件名
name=`echo $line1 | grep -ioP "(?<=/)[^/]*?(jpg|jpeg|bmp|gif|png)" `
如果在已下载文件中不存在,则为下载失败文件
if [[ `grep $name $file2` == "" ]]
then
echo $line1
fi
done
性能非常捉急,1000多条数据跑了半个多小时。
awk那的优化估计比较难,进awk代码段里写逻辑的话参考方案A
。
grep那应该可以优化,用数组散列表来替换。
数据量较大的话还是方案A
比较理想,或者写代码来处理。