J'ai un fichier journal de 8 Go (journal de production de rails). J'ai besoin de le couper entre certaines dates (lignes). Quel commandement pourrais-je utiliser pour faire cela?
Quelque chose comme
sed '1,/last date prior to chunk/d;/first date after chunk/,$d' logfile | tee cut-log | less
tee cut-log
vous permet de voir à l'écran ce qui est mis dans le fichier cut-log
.
ÉDITER:
Pour satisfaire les normes exigeantes de Fred.bear, voici une solution SED (bien que la solution AWK est beaucoup plus jolie):
b=BB; e=EE ;echo -e "AA\nAA\nBB\nBB\nCC\nCC\nDD\nDD\nEE\nEE\nFF\nFF" | sed -n ":b;/$b/b p;n;b b;:p;p;n;/$e/b e;b p;:e;p;n;/$e/b e;q"
Pour imprimer tout entre FOO et Bar inclus, essayez:
$ sed -n '/FOO/,/BAR/p' file.txt
Cela fera ce que vous voulez ...
[.____], les deux, à l'exclusion des dates de paramètres, sont indiqués.
# set Test args
set 2011-02-24 2011-02-26 "junk"
from="$1"
till="$2"
file="$3"
# EITHER ==== +++++++++
# Ouptut lines between two parameter dates INCLUDING the parameter dates
awk -v from=$from -v till=$till '
($2 >= from) && ($2 <= till) { print $0 ; next }
($2 > till) { exit }' "$file"
# OR ======== ---------
# Ouptut lines between two parameter dates EXCLUDING the parameter dates
awk -v from=$from -v till=$till '
($2 > from) && ($2 < till) { print $0 ; next }
($2 >= till) { exit }' "$file"
Il teste une date (triée) dans le champ 2 ... Voici un exemple pour les données de test
98 2011-02-05 xxxx
99 2011-02-05 xxxx
100 2011-02-06 xxxx
101 2011-02-06 xxxx
Et voici le générateur de données de test .
Si dans votre fichier journal, vous avez les dates de ce format YYYY-MM-DD
, alors, pour trouver toutes les entrées pour dire, 2011-02-10, vous pouvez faire:
grep 2011-02-10 log_file
Dis maintenant, si vous souhaitez trouver les entrées pour 2011-02-10 et 2011-02-11, utilisez à nouveau grep
mais avec plusieurs modèles:
grep -E '2011-02-10|2011-02-11' log_file
Travailler avec cette taille de fichiers est toujours difficile.
Une voie à suivre pourrait être de diviser ce fichier en quelques petits petits, pour le faire, vous pouvez utiliser la commande Split.
split -d -l 50000 ToBigFile.data file_
Même si c'est fractionné, vous pouvez toujours travailler avec le fichier comme si vous seriez l'un en utilisant une bash pour boucle
for f in `ls file_*`; do cat $f; done;
Mais au lieu du chat, vous pouvez utiliser GREP inversé pour vous débarrasser des données indésirables, cela n'est pas pertinent pour cela. (ou le genre de raffinement dont vous avez besoin).
À ce stade, vous allez juste travailler avec beaucoup de fichiers plus petits et les commandes mentionnées ci-dessus travailleront plus étouffer sur beaucoup de fichiers plus petits.
Et lorsque vous avez terminé, vous pouvez utiliser une seconde pour la boucle pour créer à nouveau le nouveau fichier plus petit.
for f in `ls file_*`; do cat $f >> NewFile.data ; done;
Mise à jour puisque nous commençons à scinder les données dans plusieurs fichiers, il y aura beaucoup de travail avec le disque dur et cela prend du temps. (Dans cette question apparemment 5min).
D'autre part, les prochaines étapes seraient probablement plus rapides.
Donc, cette méthode est probablement inutile pour une opération SIMPLE GREP, AWK, SED, mais si les modèles de recherche deviennent plus compliqués, cela pourrait devenir plus rapide.
Perl -wlne '/^2011-02-24/ .. /^2011-02-25/ and print' log_file