在 csv 文件中搜索模式

在 csv 文件中搜索模式

我有像这样的 file.csv

4,6,18,23,26
5,12,19,29,31
2,5,13,16,30
9,10,24,27,32
4,5,10,19,22
4,6,8,10,25
2,3,4,25,11

我想找到一些模式并将它们保存在另一个日志文件中 file.log,然后从第一个文件中删除它们。理想情况下是 Perl 或 grep

  • 例如,如果 x+1 = x2,在 3 的范围内,删除该行并在另一个文件中记录其存在及其存在的位置。因此,将从2,4,5,25,11中删除file.csvfile.log我会找到类似的东西row 7: 2,3,4,25,11 was removed from file.csv。我正在尝试查找序列

答案1

我认为你需要一种更强大的编程语言来实现这一点。Python 是我的选择的语言,所以这里有一个简单的脚本,带有一个简单的测试示例:

import sys

tests = [
    lambda a, b, c, d, e: a+1==b and b+1==c and c+1==d and d+1==e,
]

with open(sys.argv[1]) as f:
    for line in f:
        if any(t(*map(int, line.split(','))) for t in tests):
            sys.stderr.write('Line removed: %s\n' % line)
            continue
        print line

这显然只是测试的一个框架示例,但应该可以使用。正常运行时,它将只将不匹配的行输出到 STDOUT,将匹配的行输出到 STDERR。这使得它对于重定向到新文件非常有用。

实际操作如下:

$ python patterns.py <(echo -n 1,2,3,4,5)
Line removed: 1,2,3,4,5

$ python patterns.py <(echo -n 1,2,4,4,5)
1,2,4,4,5

一旦你加载了模式,你就可以将其传递给 csv:python patterns.py input.csv


就性能而言,Python 并不总是最快的。使用它是因为它对于 Web 开发来说足够快,并且编写时间也更快(这正是我花费时间/金钱的地方)。

你可以使用 PyPy 来加快速度。这是一个替代的 Python 运行时,基准测试结果非常出色。您可能不需要 PPA 版本(Trusty 发行版为 2.2,PPA 为 2.3.1),但您可以按照以下步骤操作:

sudo add-apt-repository ppa:pypy/ppa
sudo apt-get update
sudo apt-get install pypy

然后,您可以使用 启动脚本,pypy script.py或者如果您直接执行它,则将开头更改为#!/usr/bin/env pypy。我做了一些非常对 350000 行输入文件进行简单测试(您的示例重复50000次) 使用上述脚本。

python2在 1.417 秒内运行完成,pypy在 内运行完成0.645s。根据我的经验,使用更复杂的算法,您可能会看到更大的改进。

... 但这些都无法打败 C/C++ 同类程序。如果运行时间就是金钱,那就花点时间用更快的语言重新实现它吧。

答案2

如果我们将您的要求解释为第三个字段(列)的值应该比第二个字段(列)的值大一,那么awk您可以执行以下操作

awk -F, '
$3==$2+1 {print "row "NR": "$0" was removed from "FILENAME > "file.log"; next}1
' file.csv > newfile.csv

这将按指定的方式创建您的file.log,并将剩余的行写入newfile.csv。您可以重命名newfile.csvfile.csvafter 以模拟删除。

答案3

perl:

$ perl -i.bak -F, -ane '
    if ($F[0]+1 == $F[1] and $F[1]+1 == $F[2]) {warn "row $.: $_"} else {print}
' file.csv 2>file.log
$ cat file.log
row 7: 2,3,4,25,11
$ cat file.csv
4,6,18,23,26
5,12,19,29,31
2,5,13,16,30
9,10,24,27,32
4,5,10,19,22
4,6,8,10,25

相关内容