Deinterleave log lines [duplicate]

Aug 18 2020

Hai ereditato un server che esegue diverse app che vengono tutte visualizzate nello stesso registro.

Il tuo compito è deinterleave le righe del file di log in base alla fonte. Fortunatamente, ogni riga inizia con un tag che indica da quale app proviene.

Registri

Ogni riga avrà un aspetto simile a questo:

[app_name] Something horrible happened!
  • I tag delle app sono sempre tra parentesi quadre e conterranno solo caratteri alfanumerici e trattini bassi.
  • Tutte le righe avranno un tag app all'inizio. Non ci saranno spazi bianchi precedenti o altri caratteri.
  • Ci sarà sempre almeno uno spazio dopo il tag dell'app
  • I tag delle app non sono vuoti
  • Potrebbero esserci altre parentesi quadre più avanti su una determinata riga.
  • Potrebbe esserci o meno un messaggio dopo il tag
  • Il registro potrebbe essere vuoto
  • Non c'è limite al numero di tag di app univoci presenti nel file.

Esempio

Un intero registro potrebbe essere simile a questo:

[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

Che dovrebbe produrre tre diversi registri:

[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

Non ti vengono forniti i nomi dei tag dell'app in anticipo. È necessario determinarli solo analizzando il file di registro.

Regole e punteggio

  • Questo è il golf in codice , quindi il codice più breve vince.
  • Si applicano regole e scappatoie standard
  • Utilizza qualsiasi formato IO conveniente, a condizione che ogni riga di input sia rappresentata come una stringa, non come un tag pre-analizzato + un messaggio. Elenco non esaustivo degli output consentiti:
    • Diversi file denominati dopo ogni tag
    • Diversi elenchi di stringhe
    • Un elenco concatenato di stringhe contenente righe raggruppate per tag con o senza separatore (il separatore non deve iniziare con un tag)
    • Come sopra, ma per stdout o un file.
  • L'ordine in cui vengono emessi i registri separati è irrilevante, tuttavia le righe di registro all'interno di ogni gruppo devono mantenere l'ordine in cui sono state trovate nel file originale

Risposte

9 Noodle9 Aug 18 2020 at 03:22

Bash , 4 11 byte

Aggiunti 7 byte per correggere un bug gentilmente segnalato da Shaggy .

sort -sk1,1

Provalo online!

Esegue un ordinamento stabile (l' sargomento della riga di comando) in base al primo campo ( k1,1) separato da spazi.

7 Giuseppe Aug 18 2020 at 01:35

R , 50 46 byte

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

Provalo online!

Emette come a listcon ogni elemento named con [tag]. Ogni elemento della lista mantiene l'ordine all'interno del proprio tag. Restituisce un elenco con nome named list()vuoto per input vuoto.

-2 byte ciascuno grazie a Robin Ryder e Dominic van Essen!

5 isaacg Aug 18 2020 at 04:48

Pyth , 3 byte

ohc

Provalo online!

Il formato di input è un elenco di stringhe:

["[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"]

Come funziona il codice:

  • o: Ordinato da

  • h: Il primo elemento di

  • c: Ogni stringa suddivisa in spazi

4 JonathanAllan Aug 18 2020 at 01:55

Python , 44 byte

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

Provalo online!

Loose I / O ci consente di prendere e generare un elenco di righe. Dal momento che non dobbiamo separare i gruppi, il problema si riduce all'esecuzione di un ordinamento stabile delle righe sul prefisso di ciascuna riga fino al primo spazio, split()verranno divise anche in altri caratteri di spazio bianco ma nessuna può essere presente in la parte del tag dell'applicazione.

3 Adám Aug 18 2020 at 01:49

APL (Dyalog Extended) , 10 byte ( SBCS )

Funzione di prefisso tacito anonimo. Accetta un elenco di elenchi di caratteri come argomento. Restituisce una matrice di elenchi di caratteri, con un registro in ogni riga.

⊢⊢⌸⍨≠⊃⍤⊆¨⊢

Provalo online!

 sull'argomento,

 usa i non spazi per ...

⊆¨ partizionare ogni elenco in un elenco di elenchi (rimuove gli spazi, mantiene le sequenze di non spazi),

⊃⍤ quindi mantieni il primo [di ciascuno] (ovvero i tag),

⊢⌸⍨ usali come chiavi per raggruppare ...

 l'argomento

3 nmjcman101 Aug 18 2020 at 03:14

vim, 13 11 byte

:sor/\w\+/r

bugfix e byte save grazie a @Dingus!

Provalo online!

3 user Aug 18 2020 at 01:28

Scala, 26 byte

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

Restituisce un List[String]senza separatore in mezzo, ma è ordinato in base al tag.

Provalo in Scastie


Restituisce un Map[String,List[String]], 26 byte

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

Prende un elenco di stringhe e restituisce a Map[List[String]]dove le chiavi sono i tag ei ​​valori sono i log associati a quel tag.

Provalo in Scastie


Soluzione precedente, 66 byte

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

Provalo in Scastie (per qualsiasi motivo, snon funziona in TIO)

I log di ogni app sono separati da 2 newline (potrei essere in grado di salvare 2 byte se dovesse essere solo un carattere di nuova riga). L'input è un elenco di stringhe e l'output è una grande stringa.

2 SomoKRoceS Aug 18 2020 at 04:41

05AB1E , 3 byte

Σ#¬

Input and Output è un elenco di log.

Spiegazione:

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

Ciò mantiene anche l'ordine dei registri, come richiesto.

Provalo online!

2 Neil Aug 18 2020 at 02:27

Retina 0.8.2 , 14 13 byte

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

Provalo online! Spiegazione: poiché non è richiesto alcun separatore di gruppo di output, le righe vengono semplicemente ordinate per tag dell'app, che si ottiene catturando la corrispondenza su \w+e specificando $1come chiave di ordinamento. L'ordinamento in Retina è stabile, quindi le righe con lo stesso prefisso manterranno il loro ordine. Modifica: salvato 1 byte grazie a @FryAmTheEggman per aver indicato un modo più semplice per abbinare il tag dell'app. Nota che sebbene la corrispondenza non includa l'interlinea [, tutte le linee iniziano con [, quindi ciò non influisce sul risultato dell'ordinamento.

2 Noodle9 Aug 18 2020 at 03:42

AWK , 62 58 byte

Salvati 4 byte grazie a Dominic van Essen !!!

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

Provalo online!

Memorizza tutte le linee in una matrice associativa 2D a. La prima chiave è il primo campo (separato da spazi). Quindi tutte le righe che iniziano con lo stesso campo vengono memorizzate insieme. La seconda chiave è un indice intero crescente. La parte più dettagliata è l' ENDazione che stampa il contenuto di araggruppato per primo campo in ordine di apparizione.

1 Shaggy Aug 18 2020 at 01:32

Japt , 4 byte

Accetta l'input come un array di linee, produce un array 2D.

ü_¸g

Provalo

1 Noname Aug 18 2020 at 07:14

Io , 73 byte

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

Provalo online!

1 JoKing Aug 18 2020 at 21:44

Perl 6 , 16 byte

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

Provalo online!

Ordina in base alla prima stringa di caratteri alfanumerici, che dovrebbe essere il nome dell'app

1 DanielH. Aug 18 2020 at 01:11

Python 3 , 148127 byte

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]]

Provalo online!

1 JonathanAllan Aug 19 2020 at 01:02

V (vim) , 5 byte

úr/?]

Nota: quanto ?sopra è al posto del byte non stampabile \$\text{\x}81\$ (il carattere di controllo "No Break Here").

Provalo online!

Si noti che questo funziona con la mancanza di spazi (anche uno subito dopo la prima ]parentesi), con la presenza di []parentesi nel messaggio di log, e con la presenza di un'applicazione senza tag, Provalo online!

Come?

ú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 byte

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

Legge da un file denominato fe genera in più file in base al tag.

1 IsmaelMiguel Aug 19 2020 at 19:09

SimpleTemplate 0,84, 109 byte

Sì, è piuttosto lungo, ma fa il lavoro!

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

Questo codice genera un array con <old content>, line, <end of line>.

{@echoS} appiattisce automaticamente l'array e lo visualizza.


Ungolfed:

Sì, è un casino, ma ecco una versione più pulita:

{@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 funzione explodeè una funzione PHP standard, ma accessibile dalla mia lingua.


Puoi provarlo su: http://sandbox.onlinephpfunctions.com/code/9c66f8bacc6315ae56e7c193170e430f9cf9d902

1 BlackPanther Aug 18 2020 at 20:56

C # (.NET Core) , 181 162 160 byte

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);}});

Provalo online!

C # (Visual C # Interactive Compiler) , 179 byte

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);}})

Provalo online!

Non sono sicuro che la prima soluzione sia conforme al code gulf, quindi la seconda soluzione utilizza un'espressione lambda.

1 corvus_192 Aug 20 2020 at 03:43

Haskell, 37 byte

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

Provalo online!

1 corvus_192 Aug 20 2020 at 03:57

Ruggine, 40 byte

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

Prende un riferimento mutevole a una porzione di stringhe e lo ordina.

Provalo nel parco giochi ruggine

DominicvanEssen Aug 18 2020 at 20:30

Perl 5 -M5.10.0 -Msort = stabile, 53 byte

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

Provalo online!