Désentrelacer les lignes de journal [dupliquer]
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
R , 50 46 octets
function(r)split(r,substr(r,1,regexpr("]",r)))
Sort comme un list
avec chaque élément name
d 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!
Pyth , 3 octets
ohc
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é parh
: Le premier élément dec
: Chaque chaîne est divisée en espaces
Python , 44 octets
lambda a:sorted(a,key=lambda l:l.split()[0])
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.
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.
⊢⊢⌸⍨≠⊃⍤⊆¨⊢
⊢
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
vim, 13 11 octets
:sor/\w\+/r
correction de bogue et sauvegarde d'octets grâce à @Dingus!
Scala, 26 octets
_.sortBy(_.split("]")(0))
Renvoie un List[String]
sans séparateur entre les deux, mais il est trié par la balise.
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.
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, s
ne 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.
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.
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 $1
comme 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.
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]}
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' END
action qui imprime le contenu du a
premier champ groupé par ordre d'apparition.
Io , 73 octets
method(i,i map(split first)unique map(I,i select(split first==I))flatten)
Perl 6 , 16 octets
*.sort:{~m/\w+/}
Trie par la première chaîne de caractères alphanumériques, qui doit être le nom de l'application
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]]
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").
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
AutoHotkey, 74 octets
Loop,Read,f
{
s:=A_LoopReadLine
FileAppend,%s%`n,% StrSplit(s,"]","[")[1]
}
Lit un fichier nommé f
et produit plusieurs fichiers en fonction de la balise.
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 explode
est une fonction PHP standard, mais accessible depuis mon langage.
Vous pouvez essayer ceci sur: http://sandbox.onlinephpfunctions.com/code/9c66f8bacc6315ae56e7c193170e430f9cf9d902
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);}});
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);}})
Je ne suis pas sûr que la première solution soit conforme à code gulf, donc la deuxième solution utilise une expression lambda.
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.
Perl 5 -M5.10.0 -Msort = stable, 53 octets
say sort{(split('\]',$a))[0]cmp(split('\]',$b))[0]}<>