回答
如果所有的線具有相同的長度,目前最好的辦法,是用dd(1)
並給它一個跳過參數。
讓塊的大小是每行(包括換行)的長度,那麼你可以做:
$ dd if=filename bs=<line-length> skip=<line_no - 1> count=1 2>/dev/null
的想法是尋求過去所有的以前的線(skip=<line_no - 1>
)和讀取一行(count=1
)。由於塊大小設置爲行長度(bs=<line-length>
),因此每個塊實際上只有一行。重定向stderr,以免在最後得到惱人的統計數據。
這應該比通過程序讀取所有行然後丟棄它們之前的流式傳輸線更有效,因爲dd
將尋求文件中您想要的位置並只讀取一行來自文件的數據。
如果它不是一個固定的記錄長度的文件,你不這樣做某種形式就行了索引的開始,最好的辦法是隻使用:
head -n N filespec | tail -1
其中N
是行號你要。
不幸的是,這不會成爲3Gb文件的性能最佳的一段代碼,但有辦法使它更好。
如果文件沒有經常更改,您可能需要考慮將其編入索引。我的意思是讓另一個文件中的行偏移量作爲固定長度的記錄。
所以文件:
0000000000
0000000017
0000000092
0000001023
會給你一個快速的方法來查找每一行。只需將索引記錄大小乘以所需的行號,然後在索引文件中尋找。
然後使用該位置的值在主文件中查找,以便您可以讀取直到下一個換行符。
因此,對於第3行,您會在索引文件中找到33(索引記錄長度爲10個字符,再加上一個換行符)。讀取那裏的值,0000000092
,會給你用在主文件中的偏移量。
當然,如果文件頻繁更改,這並不是很有用,但如果您可以控制事件追加時發生的情況,您仍然可以高效地向索引添加偏移量。如果你的不是,那麼只要索引的最後修改日期早於主文件的索引,就必須重新索引。
,並根據您的更新:
更新:如果它的事項,所有的線具有相同的長度。
有了這些額外的信息,您不需要索引 - 您可以通過將記錄長度乘以記錄長度,立即尋找主文件中的正確位置(假設這些值適合您的數據類型)。
因此,像僞代碼:
def getline(fhandle,reclen,recnum):
seek to position reclen*recnum for file fhandle.
read reclen characters into buffer.
return buffer.
一個awk替代方案,其中3是行號。
awk 'NR == 3 {print; exit}' file.txt
更好的打印和退出,所以awk不會通過文件的其餘部分。 – ghostdog74 2010-05-08 14:29:53
非常好的一點 – Jamie 2010-05-08 14:59:24
快速perl的一個班輪將工作做好這個太...
$ perl -ne 'if (YOURLINENUMBER..YOURLINENUMBER) {print $_; last;}' /path/to/your/file
使用q
與sed
使搜索停止線已被打印後。
sed -n '11723{p;q}' filename
的Python(最小錯誤檢查):
#!/usr/bin/env python
import sys
# by Dennis Williamson - 2010-05-08
# for http://stackoverflow.com/questions/2794049/getting-one-line-in-a-huge-file-with-bash
# seeks the requested line in a file with a fixed line length
# Usage: ./lineseek.py LINE FILE
# Example: ./lineseek 11723 data.txt
EXIT_SUCCESS = 0
EXIT_NOT_FOUND = 1
EXIT_OPT_ERR = 2
EXIT_FILE_ERR = 3
EXIT_DATA_ERR = 4
# could use a try block here
seekline = int(sys.argv[1])
file = sys.argv[2]
try:
if file == '-':
handle = sys.stdin
size = 0
else:
handle = open(file,'r')
except IOError as e:
print >> sys.stderr, ("File Open Error")
exit(EXIT_FILE_ERR)
try:
line = handle.readline()
lineend = handle.tell()
linelen = len(line)
except IOError as e:
print >> sys.stderr, ("File I/O Error")
exit(EXIT_FILE_ERR)
# it would be really weird if this happened
if lineend != linelen:
print >> sys.stderr, ("Line length inconsistent")
exit(EXIT_DATA_ERR)
handle.seek(linelen * (seekline - 1))
try:
line = handle.readline()
except IOError as e:
print >> sys.stderr, ("File I/O Error")
exit(EXIT_FILE_ERR)
if len(line) != linelen:
print >> sys.stderr, ("Line length inconsistent")
exit(EXIT_DATA_ERR)
print(line)
參數驗證應該是好多了,有房有許多其他方面的改進。
- 1. MemoryMapped從一個巨大的文件中讀取換行符
- 2. 在Python中讀取一個巨大的文本文件
- 3. PHP在一個巨大的CSV文件
- 4. 用C++編輯一個巨大文件的第一行
- 5. 如何在Java中讀取一個巨大的HTML文件?
- 6. 讀取特定行從一個巨大的文件*快速*
- 7. 在bash中讀取一個CSV文件
- 8. 轉換一個巨大的txt文件
- 9. 從一個巨大的文件
- 10. 分裂一個巨大的gz文件
- 11. Python解析一個巨大的文件
- 12. 上傳一個巨大的SQL文件
- 13. 拆分一個巨大的KML文件
- 14. 解析一個巨大的JSON文件
- 15. 處理一個巨大的access.log文件
- 16. 從URL中讀取一個巨大的90 MB文件
- 17. 從一個巨大的文本文件(c#4.0)中讀取特定的行
- 18. 並行編譯一個巨大的C文件(最好用gcc)
- 19. 如何在bash腳本中獲取文件的第一行?
- 20. 編輯一個巨大文件的第一行和最後一行
- 21. 加入大文件到一個巨大的文件
- 22. 在一個巨大的文本文件中獲取包含字符串的所有行 - 儘可能快?
- 23. BASH - 從一個文件中獲取數,並用它
- 24. 如何獲得一個巨大的視頻文件片數據
- 25. 如何讀取一個巨大的文件的塊特定的
- 26. 將一個巨大的excel文件分割成多個文件
- 27. bash腳本去通過巨大的文件,並刪除一些行
- 28. 在bash中每天提取一個文件的行
- 29. Python:如何處理一個巨大的單行文件?
- 30. 一個巨大文件的怪異BufferedReader行爲
+1。基本上和我之後的解決方案一樣,在額外的固定記錄大小片段被添加到問題後,但具有不需要編寫自己的程序的明顯優勢。 – paxdiablo 2010-05-08 12:54:19
這太書呆子了。嘿。 dd,我喜歡它。 – JavaRocky 2010-05-08 13:00:08