我使用的是 Windows 7 64 位
我有一个很大的 .txt 文件(800 mb 以上),包含以下格式
文件以空格分隔
8232394 06774483 N 19850910 19870818 19910818 EXP.
8309716 06774483 N 19850910 19870818 19910319 REM.
4687262 06908244 N 19860917 19870818 19990815 EXP.
4687262 06908244 N 19860917 19870818 19990309 REM.
4687262 06908244 N 19860917 19870818 19950221 M184
4687262 06908244 N 19860917 19870818 19910108 M173
4687262 06908244 N 19860917 19870818 19880802 ASPN
4687263 06868897 N 19860527 19870818 19990128 M185
4687263 06868897 N 19860527 19870818 19950509 RMPN
4687263 06868897 N 19860527 19870818 19950509 ASPN
4687263 06868897 N 19860527 19870818 19950119 M184
4687263 06868897 N 19860527 19870818 19910311 ASPN
4687263 06868897 N 19860527 19870818 19910124 M173
4687264 06882047 N 19860703 19870818 19990815 EXP.
4687264 06882047 N 19860703 19870818 19990309 REM.
4687264 06882047 N 19860703 19870818 19950503 RMPN
4687264 06882047 N 19860703 19870818 19950503 ASPN
4687264 06882047 N 19860703 19870818 19950119 M184
4687264 06882047 N 19860703 19870818 19910311 ASPN
RE45781 14176526 N 20140210 20151027 20150929 ASPN
RE45786 14260890 N 20140424 20151027 20150929 ASPN
RE45790 14454285 Y 20140807 20151103 20151008 ASPN
RE45793 13445791 N 20120412 20151103 20151006 ASPN
我有另一个 .txt 文件(小),包含以下格式
4687264
4687264
4687264
RE45781
RE45786
RE45790
RE45793
现在我想从大文件中提取与小文件匹配的行,相对于第 1 列,该行仅包含小 txt 文件中存在的行
结果文件应如下所示
4687264 06882047 N 19860703 19870818 19990815 EXP.
4687264 06882047 N 19860703 19870818 19990309 REM.
4687264 06882047 N 19860703 19870818 19950503 RMPN
4687264 06882047 N 19860703 19870818 19950503 ASPN
4687264 06882047 N 19860703 19870818 19950119 M184
4687264 06882047 N 19860703 19870818 19910311 ASPN
RE45781 14176526 N 20140210 20151027 20150929 ASPN
RE45786 14260890 N 20140424 20151027 20150929 ASPN
RE45790 14454285 Y 20140807 20151103 20151008 ASPN
RE45793 13445791 N 20120412 20151103 20151006 ASPN
有什么办法吗?
我最初将其发布在 vim 通用论坛上,因为我发现 vim 能够打开大文本,但我认为这个论坛更大,因为它也可以使用其他程序来完成。
答案1
格鲁普
使用 GNU grep 你可以这样做
$ grep -f small_list.txt big_file.txt
4687264 06882047 N 19860703 19870818 19990815 EXP.
4687264 06882047 N 19860703 19870818 19990309 REM.
4687264 06882047 N 19860703 19870818 19950503 RMPN
4687264 06882047 N 19860703 19870818 19950503 ASPN
4687264 06882047 N 19860703 19870818 19950119 M184
4687264 06882047 N 19860703 19870818 19910311 ASPN
RE45781 14176526 N 20140210 20151027 20150929 ASPN
RE45786 14260890 N 20140424 20151027 20150929 ASPN
RE45790 14454285 Y 20140807 20151103 20151008 ASPN
RE45793 13445791 N 20120412 20151103 20151006 ASPN
(剪切并粘贴您的精确数据后在 Linux 上进行测试)
如果您愿意并且能够安装和使用 vim,grep 应该没有问题。
查找字符串
你也可以用本机findstr
C:> findstr /G:small_list.txt big_file.txt
4687264 06882047 N 19860703 19870818 19990815 EXP.
4687264 06882047 N 19860703 19870818 19990309 REM.
4687264 06882047 N 19860703 19870818 19950503 RMPN
4687264 06882047 N 19860703 19870818 19950503 ASPN
4687264 06882047 N 19860703 19870818 19950119 M184
4687264 06882047 N 19860703 19870818 19910311 ASPN
RE45781 14176526 N 20140210 20151027 20150929 ASPN
RE45786 14260890 N 20140424 20151027 20150929 ASPN
RE45790 14454285 Y 20140807 20151103 20151008 ASPN
RE45793 13445791 N 20120412 20151103 20151006 ASPN
我之所以grep
首先提到这一点只是出于习惯,而且是因为我经常忘记它findstr
并不像我以前认为的那么愚蠢。
警告
我很确定 grep 处理非常大的文件不会有问题。我不太确定 findstr 是否可行,但我想不出任何理由不去尝试一下。
附录:
常用表达
grep
和都findstr
可以找到固定字符串,但它们也可以与常用表达。
如果要在每行的第一个单词中查找这些字符串,则可以在字符串前面加上插入符号,^
以指示要查找的字符串必须位于行的开头。
^4687264
^RE45781
^RE45786
^RE45790
^RE45793
您可以在vim中使用:%s/^/^/
- 您也可以使用 sed、awk、perl 等来轻松编辑搜索字符串文件。请注意,^
搜索表达式(替代)命令的一部分s
是元字符,表示“行首”。第二个^
是在替换字符串部分,它表示文字字符^
。
如果我不想编辑要找到的字符串文件,我会做类似的事情
sed -e 's/^/^/' < small_list.txt > temp.txt; grep -f temp.txt big_file.txt; rm temp.txt
grep
假设使用正则表达式。findstr
您需要将/R
选项添加到命令中(未经测试)。
答案2
电源外壳
不知道运行时性能,但 powershell 在所有当前 Windows 操作系统上都默认安装。
$small = (gc small.txt | group).Name
gc large.txt | ? {$small -contains $_.Split(" ")[0]}
分解
$small = (gc small.txt | group).Name
- Get-Content of small.txt
- Group the content to retain a list of unique values as to speed up the search
- Store in $small variable
gc large.txt | ? {$small -contains $_.Split(" ")[0]}
- Get-Content of large.txt
- ? => where clause
- $_ contains a complete line from large.txt.
Split it up by spaces and just select the first element of that result
- Search the first element in the $small list