我的问题总结如下:
我有两个文本文件(已下载.txt和列表.txt)
list.txt 包含 URL 列表,例如:
http://example.com/file1.exe
http://example.com/file2.exe
http://example.com/file3.exe
http://example.com/file4.exe
http://example.com/file5.exe
已下载.txt包含已下载的文件列表:
file1.exe
file2.exe
file3.exe
file5.exe
我想做的是比较两个文件,以便我可以看到哪些文件尚未下载(在本例中为file4.exe
我将如何实现这一目标?
我尝试这样做,让我们说结果是灾难性的(10m+ "结果",出于某种原因,我不得不继续按 Enter 才能让它运行。另外,只有 144k 行):
while read url; do
if ! grep "$url" downloaded.txt; then
echo $url;
fi;
done < list.txt >> files_to_download.txt
使用 awk
通过使用 URL 中的最后一个元素来比较两个文件:
$ awk -F/ 'FNR==NR {downloaded[$0]=$0; next} !($NF in downloaded)' downl list
http://example.com/file4.exe
这会循环文件downloaded.txt
并将其值存储在数组downloaded[]
中。然后,它遍历文件list.txt
并检查数组中是否出现最后一个/
片。如果没有,它将打印该行。
使用grep
,您可以从文件名中读取模式(-f
选项)。在您的情况下,您可以反转匹配 ( -v
),假设 downloaded.txt
中的文件名不会出现在路径中的任何位置:
grep -vFf downloaded.txt list.txt
-F
固定字符串匹配。
这将提供http://example.com/file4.exe
作为输出。要获取文件名,请执行以下操作:
grep -vFf downloaded.txt list.txt | awk -F/ '{ print $NF }'
输出file4.exe
.
例:
% cat list.txt
http://example.com/file1.exe
http://example.com/file2.exe
http://example.com/file3.exe
http://example.com/file4.exe
http://example.com/file5.exe
% cat dl.txt
file1.exe
file2.exe
file3.exe
file5.exe
% grep -vFf dl.txt list.txt
http://example.com/file4.exe
% grep -vFf dl.txt list.txt | awk -F/ '{ print $NF }'
file4.exe