web-dev-qa-db-fra.com

Comment couper une partie du fichier journal?

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?

18
user5113

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"
12
asoundmove

Pour imprimer tout entre FOO et Bar inclus, essayez:

$ sed -n '/FOO/,/BAR/p' file.txt
6
dogbane

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 .

5
Peter.O

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
4
Barun

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.

1
Johan
Perl -wlne '/^2011-02-24/ .. /^2011-02-25/ and print' log_file
0
charlesbridge