J'ai un énorme fichier où j'ai besoin de trier et de fusionner 3 lignes qui ont un motif correspondant "vm" et en ont besoin en une seule ligne, comme ci-dessous

Kfg-ap4 est le nom du serveur, nous ne pouvons l'avoir qu'une seule fois ce sera bien lors du tri .. J'ai essayé awk avec getline mais il me manque en quelque sorte pour l'adapter ..

Awk '/ vm / {printf $ 0 ""; getline; imprimer $ 0} 'mem_overc

**[kfg-ap4] out: vm.overcommit_memory = 0 [kfg-ap4] out: vm.overcommit_ratio = 50 [kfg-ap4] out: vm.nr_overcommit_hugepages = 0**


[kfg-ap4] Executing task 'moc'
[kfg-ap4] sudo: /sbin/sysctl -A | grep overcommit
[kfg-ap4] out:
[kfg-ap4] out: We trust you have received the usual lecture from the local System
[kfg-ap4] out: Administrator. It usually boils down to these three things:
[kfg-ap4] out:
[kfg-ap4] out:     #1) Respect the privacy of others.
[kfg-ap4] out:     #2) Think before you type.
[kfg-ap4] out:     #3) With great power comes great responsibility.
[kfg-ap4] out:
[kfg-ap4] out: sudo password:
[kfg-ap4] out: vm.overcommit_memory = 0
[kfg-ap4] out: vm.overcommit_ratio = 50
[kfg-ap4] out: vm.nr_overcommit_hugepages = 0
[kfg-ap4] out:

================================================== ====================

Les données réelles sont comme ci-dessous et le reste des données est le même sauf les noms de serveur

[kfg-ap3] Executing task 'moc'
[kfg-ap3] sudo: /sbin/sysctl -A | grep overcommit
[kfg-ap3] out:
[kfg-ap3] out: We trust you have received the usual lecture from the local System
[kfg-ap3] out: Administrator. It usually boils down to these three things:
[kfg-ap3] out:
[kfg-ap3] out:     #1) Respect the privacy of others.
[kfg-ap3] out:     #2) Think before you type.
[kfg-ap3] out:     #3) With great power comes great responsibility.
[kfg-ap3] out:
[kfg-ap3] out: sudo password:
[kfg-ap3] out: vm.overcommit_memory = 0
[kfg-ap3] out: vm.overcommit_ratio = 50
[kfg-ap3] out: vm.nr_overcommit_hugepages = 0
[kfg-ap3] out:

[kfg-ap4] Executing task 'moc'
[kfg-ap4] sudo: /sbin/sysctl -A | grep overcommit
[kfg-ap4] out:
[kfg-ap4] out: We trust you have received the usual lecture from the local System
[kfg-ap4] out: Administrator. It usually boils down to these three things:
[kfg-ap4] out:
[kfg-ap4] out:     #1) Respect the privacy of others.
[kfg-ap4] out:     #2) Think before you type.
[kfg-ap4] out:     #3) With great power comes great responsibility.
[kfg-ap4] out:
[kfg-ap4] out: sudo password:
[kfg-ap4] out: vm.overcommit_memory = 0
[kfg-ap4] out: vm.overcommit_ratio = 50
[kfg-ap4] out: vm.nr_overcommit_hugepages = 0
[kfg-ap4] out:
0
user5149108 8 août 2016 à 11:08

3 réponses

Meilleure réponse
$ awk '/vm/ {printf "%s%s", $0, (++i%3?OFS:ORS)}' log.txt
[kfg-ap4] out: vm.overcommit_memory = 0 [kfg-ap4] out: vm.overcommit_ratio = 50 [kfg-ap4] out: vm.nr_overcommit_hugepages = 0
[kfg-ap4] out: vm.overcommit_memory = 0 [kfg-ap4] out: vm.overcommit_ratio = 50 [kfg-ap4] out: vm.nr_overcommit_hugepages = 0

Marcher à travers:

/vm/ {                                 # if vm on the record
    printf "%s%s", $0, (++i%3?OFS:ORS) # print record and OFS
}                                      # every 3rd time print ORS

Puisqu'il y avait en fait plus de 3 lignes dans un groupe, utilisez ceci:

$ awk '/vm/ {buf=buf OFS $0; next} buf!="" {print buf; buf=""}'

Il met en mémoire tampon les enregistrements et les imprime après avoir rencontré un enregistrement qui ne correspond pas à /vm/. Il peut y avoir un problème si vous avez des groupes consécutifs dans votre fichier. Vous pouvez vous retrouver avec des lignes plus longues que prévu.

$ cat > process.awk
/vm/ {              # if vm string in the record
    buf=buf OFS $0  # append the record $0 to the buffer variable buf
    next            # skip the rest of script for this record, ie.
}                   # only records without vm match get past this point
buf!="" {           # if the buffer is not empty
    print buf       # print it out
    buf=""          # empty the buffer
}
$ awk -f process.awk log.txt
0
James Brown 8 août 2016 à 14:50

Une autre réponse utilisant uniquement sed

/vm/{
H
x
s/\n/ /g
s/ \[kfg-ap.\] out: / /
x
blab
}
x
p
:lab

Invoquer comme ceci (enregistrer le fichier ci-dessus sous filter.sed):

sed -n -f filter.sed text.txt 

Si vm est mis en correspondance, puis stocke dans le tampon de maintien. Échange ensuite tout le tampon pour supprimer les sauts de ligne et les préfixes kfg inutiles dans la ligne, échangez à nouveau.

S'il ne correspond pas, échangez à nouveau le tampon et imprimez.

Plutôt simple et fonctionne très bien (cornercase: si le journal se termine par les lignes vm, elles peuvent être omises)

0
Jean-François Fabre 8 août 2016 à 13:06

Vous y étiez presque: Accumulez simplement dans une variable et imprimez à la fin:

awk 'BEGIN{s="";} /vm/ {s = s $0 " "} END {print s}' log.txt

Vous pouvez également utiliser votre construction exacte et convertir les nouvelles lignes:

awk '/vm/ {printf $0 " ";getline; print $0}' log.txt | tr "\n" " "
1
Jean-François Fabre 8 août 2016 à 08:17