我有像这样的 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.csv
,file.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.csv
为file.csv
after 以模拟删除。
答案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