我正在编写一个awk脚本,我想在文件中搜索一些字符串。我面临的问题是......
该文件非常庞大,从某种意义上说......大约有100万行。
如果我搜索文件最后一行的字符串,那么我不必要地遍历其余的起始行,因此我正在寻找一些命令,当我将字符串作为参数时,它应该给我文件的行号..或者我想对文件进行二进制搜索,任何关于此的重定向。
只是另外一个注释,字符串不是单个字符串,我有一个字符串可以在一个时间点搜索
答案 0 :(得分:1)
无论你做什么,如果数据在一个文件中,它必须先读入内存,然后才能进行任何处理(无论效率如何),排序,搜索等。
你的内存耗尽,还是你关心时间?如果记忆不是问题,那么近百万条记录看起来不那么大。
如果您只想确定数据文件中是否存在某个字符串,可以尝试使用grep
。例如,
grep -n target_string data.txt
如果在文件中找到目标,将打印行号和行号。有关grep man page的更多信息。
如果您想在文件中找到处理一行,那么grep
将无效,您将不得不使用awk
(就像您一样)提到),或者查看sed
或用Python或其他语言编写自定义脚本。在所有情况下,都必须以这种或那种方式读取文件。
或许将文件分成块然后处理特定部分(如果您可以提前确定搜索的位置 - 尽管您的问题不太可能发出这种声音)
答案 1 :(得分:0)
你有一百万行,但文件有多大? 100万行1个字符的行给出了大约1MB的文件大小,这很小,并且在时间上将花费时间来解析。 80个字符/行给出了76MB的文件大小,这比1个字符/行文件需要更多的时间来阅读,但是简单的查找时间不会是可怕的。
如果您正在查看许多兆字节,那么您需要读取一次文件并创建它的索引,但是如果这是一次性或罕见的任务,则创建此类索引所花费的时间不会超过使用grep
或awk
直接对文件进行搜索的费用。
同样,如果你需要针对不断变化的文件执行此操作,再次拥有索引将不会获得太多,因为索引将过时并且您需要刷新索引(需要重新扫描索引)完整文件)以获得准确的结果。
我们需要更多关于总体问题的详细信息,因为它听起来还有其他一些不明确的要求:您经常进行此搜索的频率如何?文件的静态程度如何?你怎么处理结果?简而言之,您在做什么需要/应用程序?
那就是说,如果你想创建一个索引,那么它只是一个逐行读取文件,在白色空间分割,然后存储在某个数据存储区(SQLite数据库?BDB数据库?)中的单词使用它出现的行,然后直接查询该商店。希望您可以看到初始生成非常昂贵,因此只有在文件是静态的并且您正在对文件进行多次搜索时才值得这样做。
答案 2 :(得分:0)
您提到对文件进行二进制搜索,因此我们可以假设您的输入已排序,并且您要查找的字符串将锚定到该行的开头。要进行二进制搜索,有一个名为look
的实用程序,但它不会报告行号。要获取行号,只需在行输入中附加行号:
# Append line numbers to each line
$ awk '{print $0, NR}' input > tmp
# Do a binary search, looking for the string 'string'
$ look string tmp
look
和seq
不是标准实用程序,因此可能无法在您的平台上使用。