J'ai File.csv qui ressemble à ceci
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
Je souhaite rechercher des modèles, les enregistrer dans un autre fichier journal file.log
et les supprimer du premier fichier. Perl ou grep idéalement
2,4,5,25,11
sera supprimé de file.csv
et dans file.log
, je trouverais quelque chose comme row 7: 2,3,4,25,11 was removed from file.csv
. J'essaie de trouver des séquencesSi nous interprétons votre exigence comme signifiant que la valeur du troisième champ (colonne) doit être supérieure de un à celle du deuxième champ (colonne), alors avec awk
vous pouvez faire des choses comme
awk -F, '
$3==$2+1 {print "row "NR": "$0" was removed from "FILENAME > "file.log"; next}1
' file.csv > newfile.csv
qui créera votre file.log
comme spécifié et écrira les lignes restantes dans newfile.csv
. Vous pouvez renommer newfile.csv
en file.csv
après pour simuler la suppression.
Je pense que vous avez besoin d'un langage de programmation plus lourd pour cela. Python est mon langage de choix . Voici donc un script simple avec un exemple simple de test:
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
Ce n'est évidemment qu'un exemple squelette de tests, mais il devrait être utilisable. En cours d’exécution normale, seules les lignes qui ne correspondent pas à STDOUT et celles correspondant à STDERR seront affichées. Cela le rend utile pour rediriger vers un nouveau fichier.
Ici c'est en action:
$ 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
Une fois que vous avez chargé des motifs, vous pouvez simplement passer le csv: python patterns.py input.csv
En termes de performances, Python n'est pas toujours le plus rapide. I utilisez-le parce que c'est assez rapide pour le développement Web et que le temps nécessaire pour écrire est beaucoup plus rapide (ce qui me coûte temps/argent) .
Vous pouvez accélérer les choses avec PyPy. Ceci est une alternative Python runtime qui teste étonnamment bien . Vous n'avez peut-être pas besoin de la version PPA (Trusty est la version 2.2, PPA est la 2.3.1), mais voici comment procéder:
Sudo add-apt-repository ppa:pypy/ppa
Sudo apt-get update
Sudo apt-get install pypy
Vous lanceriez ensuite votre script avec pypy script.py
ou, si vous l'exécutez, changez directement le Shebang d'ouverture en #!/usr/bin/env pypy
. J'ai fait quelques très tests simples sur un fichier d'entrée de 350000 lignes (votre exemple répété 50000 fois ) avec ce qui précède scénario.
python2
l'a exécuté en 1.417s et pypy
en 0.645s
. D'après mon expérience, vous constaterez probablement une amélioration encore plus importante avec des algues plus complexes.
... Mais oui, rien de tout cela ne va battre l'équivalent C/C++. Si le temps que cela prend est de l'argent, passez un peu de temps à le réimplémenter dans un langage plus rapide.
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