Désentrelacer les lignes de journal [dupliquer]

Aug 18 2020

Vous avez hérité d'un serveur qui exécute plusieurs applications qui sont toutes générées dans le même journal.

Votre tâche consiste à désentrelacer les lignes du fichier journal par source. Heureusement, chaque ligne commence par une balise qui indique de quelle application elle provient.

Journaux

Chaque ligne ressemblera à ceci:

[app_name] Something horrible happened!
  • Les balises d'application sont toujours entre crochets et ne contiennent que des caractères alphanumériques et des traits de soulignement.
  • Toutes les lignes auront une balise app au début. Il n'y aura pas d'espace blanc précédent ni aucun autre caractère.
  • Il y aura toujours au moins un espace après la balise app
  • Les balises d'application ne sont pas vides
  • Il peut y avoir d'autres crochets plus tard sur une ligne donnée.
  • Il peut y avoir ou non un message après la balise
  • Le journal peut être vide
  • Il n'y a pas de limite au nombre de balises d'application uniques présentes dans le fichier.

Exemple

Un journal entier pourrait ressembler à ceci:

[weather] Current temp: 83F
[barkeep] Fish enters bar
[barkeep] Fish orders beer
[stockmarket] PI +3.14
[barkeep] Fish leaves bar
[weather] 40% chance of rain detected

Ce qui devrait générer trois journaux différents:

[weather] Current temp: 83F
[weather] 40% chance of rain detected
[barkeep] Fish enters bar
[barkeep] Fish orders beer
[barkeep] Fish leaves bar
[stockmarket] PI +3.14

Vous ne recevez pas les noms des balises d'application à l'avance. Vous devez les déterminer uniquement en analysant le fichier journal.

Règles et notation

  • C'est du code-golf , donc le code le plus court l'emporte.
  • Les règles standard et les lacunes s'appliquent
  • Utilisez n'importe quel format d'E / S pratique, à condition que chaque ligne d'entrée soit représentée sous forme de chaîne et non de balise + message pré-analysée. Liste non exhaustive des sorties autorisées:
    • Plusieurs fichiers nommés après chaque balise
    • Plusieurs listes de chaînes
    • Une liste concaténée de chaînes contenant des lignes regroupées par balise avec ou sans séparateur (le séparateur ne doit pas commencer par une balise)
    • Idem que ci-dessus, mais vers stdout ou un fichier.
  • L'ordre dans lequel les journaux séparés sont sortis n'est pas pertinent, mais les lignes de journal dans chaque groupe doivent conserver l'ordre dans lequel elles ont été trouvées dans le fichier d'origine

Réponses

9 Noodle9 Aug 18 2020 at 03:22

Bash , 4 11 octets

Ajout de 7 octets pour corriger un bug gentiment signalé par Shaggy .

sort -sk1,1

Essayez-le en ligne!

Effectue un tri stable (l' sargument de ligne de commande) basé sur le premier champ ( k1,1) séparé par un espace.

7 Giuseppe Aug 18 2020 at 01:35

R , 50 46 octets

function(r)split(r,substr(r,1,regexpr("]",r)))

Essayez-le en ligne!

Sort comme un listavec chaque élément named avec le [tag]. Chaque élément de liste maintient l'ordre dans sa balise. Renvoie une liste nommée named list()vide pour une entrée vide.

-2 octets chacun grâce à Robin Ryder et Dominic van Essen!

5 isaacg Aug 18 2020 at 04:48

Pyth , 3 octets

ohc

Essayez-le en ligne!

Le format d'entrée est une liste de chaînes:

["[weather] Current temp: 83F","[barkeep] Fish enters bar","[barkeep] Fish orders beer","[stockmarket] PI +3.14","[barkeep] Fish leaves bar","[weather] 40% chance of rain detected"]

Comment fonctionne le code:

  • o: Commandé par

  • h: Le premier élément de

  • c: Chaque chaîne est divisée en espaces

4 JonathanAllan Aug 18 2020 at 01:55

Python , 44 octets

lambda a:sorted(a,key=lambda l:l.split()[0])

Essayez-le en ligne!

Les E / S lâches nous permettent de prendre, et d'obtenir, une liste de lignes. Comme nous n'avons pas à séparer les groupes, le problème est réduit à effectuer une sorte stable des lignes sur le préfixe de chaque ligne jusqu'au premier espace, split()se diviseront également en d'autres caractères d'espace blanc mais aucun ne peut être présent la partie de la balise d'application.

3 Adám Aug 18 2020 at 01:49

APL (Dyalog Extended) , 10 octets ( SBCS )

Fonction de préfixe tacite anonyme. Prend une liste de listes de caractères comme argument. Renvoie une matrice de listes de caractères, avec un journal dans chaque ligne.

⊢⊢⌸⍨≠⊃⍤⊆¨⊢

Essayez-le en ligne!

 sur l'argument,

 utiliser les non-espaces pour…

⊆¨ partitionner chaque liste en une liste de listes (supprime les espaces, conserve les séries de non-espaces),

⊃⍤ puis gardez le premier [de chaque] (c'est-à-dire les balises),

⊢⌸⍨ utilisez-les comme clés pour regrouper…

 l'argument

3 nmjcman101 Aug 18 2020 at 03:14

vim, 13 11 octets

:sor/\w\+/r

correction de bogue et sauvegarde d'octets grâce à @Dingus!

Essayez-le en ligne!

3 user Aug 18 2020 at 01:28

Scala, 26 octets

_.sortBy(_.split("]")(0))

Renvoie un List[String]sans séparateur entre les deux, mais il est trié par la balise.

Essayez-le dans Scastie


Renvoie a Map[String,List[String]], 26 octets

_ groupBy(_.split("]")(0))

Prend une liste de chaînes et retourne a Map[List[String]]où les clés sont les balises et les valeurs sont les journaux associés à cette balise.

Essayez-le dans Scastie


Solution précédente, 66 octets

_ groupBy{case s"[$t]$r"=>t}map(_._2 mkString "\n")mkString "\n"*2

Essayez-le dans Scastie (pour une raison quelconque, sne fonctionne pas dans TIO)

Les journaux de chaque application sont séparés par 2 nouvelles lignes (je pourrais peut-être enregistrer 2 octets s'il ne s'agissait que du seul caractère de nouvelle ligne). L'entrée est une liste de chaînes et la sortie est une grande chaîne.

2 SomoKRoceS Aug 18 2020 at 04:41

05AB1E , 3 octets

Σ#¬

Entrée et sortie est une liste de journaux.

Explication:

Σ#¬
Σ          Sort by:
 #         Split (each log) by spaces
  ¬        Head (which is the tagname)

Cela permet également de conserver l'ordre des journaux, selon les besoins.

Essayez-le en ligne!

2 Neil Aug 18 2020 at 02:27

Retina 0.8.2 , 14 13 octets

O$`(\w+).*
$1

Essayez-le en ligne! Explication: Étant donné qu'aucun séparateur de groupe de sortie n'est requis, les lignes sont simplement triées par balise d'application, ce qui est obtenu en capturant la correspondance \w+et en spécifiant $1comme clé de tri. Le tri dans Retina est stable, de sorte que les lignes avec le même préfixe conservent leur ordre. Edit: 1 octet enregistré grâce à @FryAmTheEggman pour avoir souligné un moyen plus simple de faire correspondre la balise d'application. Notez que bien que la correspondance n'inclut pas le [début, toutes les lignes commencent par [, donc cela n'affecte pas le résultat du tri.

2 Noodle9 Aug 18 2020 at 03:42

AWK , 62 58 octets

Sauvegardé 4 octets grâce à Dominic van Essen !!!

{a[$1][i++]=$0}END{for(k in a)for(j in a[k])print a[k][j]}

Essayez-le en ligne!

Stocke toutes les lignes dans un tableau associatif 2D a. La première clé est le premier champ (séparé par un espace). Ainsi, toutes les lignes commençant par le même champ sont stockées ensemble. La deuxième clé est un index entier croissant. La partie la plus verbeuse est l' ENDaction qui imprime le contenu du apremier champ groupé par ordre d'apparition.

1 Shaggy Aug 18 2020 at 01:32

Japt , 4 octets

Prend l'entrée sous la forme d'un tableau de lignes, génère un tableau 2D.

ü_¸g

Essayez-le

1 Noname Aug 18 2020 at 07:14

Io , 73 octets

method(i,i map(split first)unique map(I,i select(split first==I))flatten)

Essayez-le en ligne!

1 JoKing Aug 18 2020 at 21:44

Perl 6 , 16 octets

*.sort:{~m/\w+/}

Essayez-le en ligne!

Trie par la première chaîne de caractères alphanumériques, qui doit être le nom de l'application

1 DanielH. Aug 18 2020 at 01:11

Python 3 , 148 127 octets

a={}
try:
 while 1:
  b=input();c=b.split("]")[0]
  if 1-(c in a):a[c]=[]
  a[c]+=[b]
except:[print(e)for k in a for e in a[k]]

Essayez-le en ligne!

1 JonathanAllan Aug 19 2020 at 01:02

V (vim) , 5 octets

úr/?]

Remarque: ce qui ?précède est à la place de l'octet non imprimable \$\text{\x}81\$ (le caractère de contrôle "No Break Here").

Essayez-le en ligne!

Notez que cela fonctionne avec un manque d'espaces (même un directement après le premier ]crochet), avec la présence de []crochets dans le message du journal, et avec la présence d'une application non balisée, essayez-le en ligne!

Comment?

úr/?]
ú     - sort by:
 r    -   with flag=r: use match (default behaviour is to use what's after the match)
  /   -     with the pattern:
   ?  -       (byte 83) a shortcut for .\{-}
                                       .     - match any character
                                        \{-} - 0 or more times matching as few times as possible
    ] -       match a literal ']' character
1 EngineerToast Aug 19 2020 at 03:09

AutoHotkey, 74 octets

Loop,Read,f
{
s:=A_LoopReadLine
FileAppend,%s%`n,% StrSplit(s,"]","[")[1]
}

Lit un fichier nommé fet produit plusieurs fichiers en fonction de la balise.

1 IsmaelMiguel Aug 19 2020 at 19:09

SimpleTemplate 0.84, 109 octets

Ouais, c'est assez long, mais ça fait le boulot!

{@callexplode intoL EOL,argv.0}{@eachL}{@if_ matches"@^(\[.*\])@"M}{@setS.[M.1]S.[M.1],_,EOL}{@/}{@/}{@echoS}

Ce code génère un tableau avec <old content>, line, <end of line>.

{@echoS} aplatit automatiquement le tableau et l'affiche.


Non golfé:

Oui, c'est un gâchis, mais voici une version plus propre:

{@call explode into lines EOL, argv.0}
{@set storage null}
{@each lines as line}
    {@if line matches "@^(\[.*\])@" match}
        {@set storage.[match.1] storage.[match.1], line, EOL}
    {@/}
{@/}
{@echo storage}

La fonction explodeest une fonction PHP standard, mais accessible depuis mon langage.


Vous pouvez essayer ceci sur: http://sandbox.onlinephpfunctions.com/code/9c66f8bacc6315ae56e7c193170e430f9cf9d902

1 BlackPanther Aug 18 2020 at 20:56

C # (.NET de base) , 181 162 160 octets

input.GroupBy(l=>l.Split()[0]).ToList().ForEach((g)=>{using(var sw = new StreamWriter(g.Key.Trim('[').Trim(']')+".log")){foreach(var v in g)sw.WriteLine(v);}});

Essayez-le en ligne!

C # (compilateur interactif Visual C #) , 179 octets

i=>i.GroupBy((l)=>{return l.Split(' ')[0];}).ToList().ForEach((g)=>{using(var sw = new StreamWriter(g.Key.Trim(new char[]{'[',']'})+".log")){foreach(var v in g)sw.WriteLine(v);}})

Essayez-le en ligne!

Je ne suis pas sûr que la première solution soit conforme à code gulf, donc la deuxième solution utilise une expression lambda.

1 corvus_192 Aug 20 2020 at 03:43

Haskell, 37 octets

import Data.List
f=sortOn(head.words)

Essayez-le en ligne!

1 corvus_192 Aug 20 2020 at 03:57

Rouille, 40 octets

|a|a.sort_by_key(|x|x.split("]").next())

Prend une référence mutable à une tranche de chaînes et la trie.

Essayez-le sur le terrain de jeu de la rouille

DominicvanEssen Aug 18 2020 at 20:30

Perl 5 -M5.10.0 -Msort = stable, 53 octets

say sort{(split('\]',$a))[0]cmp(split('\]',$b))[0]}<>

Essayez-le en ligne!