Desintercalar linhas de registro [duplicado]

Aug 18 2020

Você herdou um servidor que executa vários aplicativos que geram o mesmo log.

Sua tarefa é desintercalar as linhas do arquivo de log por origem. Felizmente, cada linha começa com uma tag que indica de qual aplicativo ela é.

Histórico

Cada linha será parecida com isto:

[app_name] Something horrible happened!
  • As tags de aplicativo estão sempre entre colchetes e conterão apenas caracteres alfanuméricos e sublinhados.
  • Todas as linhas terão uma tag de aplicativo no início. Não haverá espaço em branco anterior ou qualquer outro caractere.
  • Sempre haverá pelo menos um espaço após a tag do aplicativo
  • As tags do aplicativo não estão vazias
  • Pode haver outros colchetes posteriormente em qualquer linha.
  • Pode haver ou não uma mensagem após a tag
  • O log pode estar vazio
  • Não há limite de quantas tags de aplicativo exclusivas estarão presentes no arquivo.

Exemplo

Um registro inteiro pode ter a seguinte aparência:

[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

Que deve gerar três registros diferentes:

[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

Os nomes das tags de aplicativo não são fornecidos a você com antecedência. Você deve determiná-los apenas analisando o arquivo de log.

Regras e pontuação

  • Este é o código de golfe , então o código mais curto vence.
  • Regras padrão e brechas se aplicam
  • Use qualquer formato IO conveniente, desde que cada linha de entrada seja representada como uma string, não uma tag + mensagem pré-analisada. Lista não exaustiva de resultados permitidos:
    • Vários arquivos nomeados após cada tag
    • Várias listas de strings
    • Uma lista concatenada de strings contendo linhas agrupadas por tag com ou sem separador (o separador não deve começar com uma tag)
    • O mesmo que acima, mas para stdout ou um arquivo.
  • A ordem em que os logs separados são produzidos é irrelevante, no entanto, as linhas de log dentro de cada grupo devem preservar a ordem em que foram encontradas no arquivo original

Respostas

9 Noodle9 Aug 18 2020 at 03:22

Bash , 4 11 bytes

Adicionados 7 bytes para corrigir um bug gentilmente apontado por Shaggy .

sort -sk1,1

Experimente online!

Executa uma classificação estável (o sargumento da linha de comando) com base no primeiro campo ( k1,1) separado por um espaço em branco.

7 Giuseppe Aug 18 2020 at 01:35

R , 50 46 bytes

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

Experimente online!

Produz como a listcom cada elemento named com [tag]. Cada elemento da lista mantém a ordem em sua tag. Retorna uma lista nomeada named list()vazia para entrada vazia.

-2 bytes cada graças a Robin Ryder e Dominic van Essen!

5 isaacg Aug 18 2020 at 04:48

Pyth , 3 bytes

ohc

Experimente online!

O formato de entrada é uma lista de strings:

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

Como funciona o código:

  • o: Ordenar por

  • h: O primeiro elemento de

  • c: Cada string é dividida em espaços

4 JonathanAllan Aug 18 2020 at 01:55

Python , 44 bytes

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

Experimente online!

O I / O frouxo nos permite obter e resultar em uma lista de linhas. Uma vez que não temos que separar os grupos, o problema é reduzido a realizar uma espécie de estável das linhas no prefixo de cada linha até o primeiro espaço, split()irão se dividir em alguns outros caracteres de espaço em branco também, mas nenhum pode estar presente em a parte da tag do aplicativo.

3 Adám Aug 18 2020 at 01:49

APL (Dyalog Extended) , 10 bytes ( SBCS )

Função de prefixo tácito anônima. Obtém uma lista de listas de caracteres como argumento. Retorna uma matriz de listas de caracteres, com um log em cada linha.

⊢⊢⌸⍨≠⊃⍤⊆¨⊢

Experimente online!

 no argumento,

 use os não-espaços para ...

⊆¨ particionar cada lista em uma lista de listas (remove espaços, mantém execuções de não espaços),

⊃⍤ então mantenha o primeiro [de cada] (ou seja, as tags),

⊢⌸⍨ use-as como chaves para o grupo ...

 o argumento

3 nmjcman101 Aug 18 2020 at 03:14

vim, 13 11 bytes

:sor/\w\+/r

correção de bugs e byte save graças a @Dingus!

Experimente online!

3 user Aug 18 2020 at 01:28

Scala, 26 bytes

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

Retorna um List[String]sem separador, mas é classificado pela tag.

Experimente no Scastie


Retorna um Map[String,List[String]], 26 bytes

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

Obtém uma lista de strings e retorna um Map[List[String]]onde as chaves são as tags e os valores são os logs associados a essa tag.

Experimente no Scastie


Solução anterior, 66 bytes

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

Experimente no Scastie (por qualquer motivo, snão funciona no TIO)

Os logs de cada aplicativo são separados por 2 novas linhas (eu poderia economizar 2 bytes se fosse apenas um caractere de nova linha). A entrada é uma lista de strings e a saída é uma grande string.

2 SomoKRoceS Aug 18 2020 at 04:41

05AB1E , 3 bytes

Σ#¬

Entrada e saída é uma lista de registros.

Explicação:

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

Isso também mantém a ordem dos logs, conforme necessário.

Experimente online!

2 Neil Aug 18 2020 at 02:27

Retina 0.8.2 , 14 13 bytes

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

Experimente online! Explicação: Como nenhum separador de grupo de saída é necessário, as linhas são simplesmente classificadas por tag de aplicativo, o que é obtido capturando a correspondência \w+e especificando $1como chave de classificação. A classificação na Retina é estável, para que as linhas com o mesmo prefixo mantenham sua ordem. Edit: Salvo 1 byte graças a @FryAmTheEggman por apontar uma maneira mais fácil de combinar a tag do aplicativo. Observe que embora a correspondência não inclua o entrelinhas [, todas as linhas começam com [, de modo que isso não afeta o resultado da classificação.

2 Noodle9 Aug 18 2020 at 03:42

AWK , 62 58 bytes

Economizei 4 bytes graças a Dominic van Essen !!!

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

Experimente online!

Armazena todas as linhas em uma matriz associativa 2D a. A primeira chave é o primeiro campo (separado por um espaço em branco). Portanto, todas as linhas que começam com o mesmo campo são armazenadas juntas. A segunda chave é um índice inteiro crescente. A parte mais detalhada é a ENDação que imprime o conteúdo do aagrupado pelo primeiro campo em ordem de aparecimento.

1 Shaggy Aug 18 2020 at 01:32

Japt , 4 bytes

Recebe entrada como uma matriz de linhas, produz uma matriz 2D.

ü_¸g

Tente

1 Noname Aug 18 2020 at 07:14

Io , 73 bytes

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

Experimente online!

1 JoKing Aug 18 2020 at 21:44

Perl 6 , 16 bytes

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

Experimente online!

Classifica pela primeira string de caracteres alfanuméricos, que deve ser o nome do aplicativo

1 DanielH. Aug 18 2020 at 01:11

Python 3 , 148 127 bytes

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

Experimente online!

1 JonathanAllan Aug 19 2020 at 01:02

V (vim) , 5 bytes

úr/?]

Nota: O ?código acima está no lugar do byte não imprimível \$\text{\x}81\$ (o caractere de controle "No Break Here").

Experimente online!

Observe que isso funciona com a falta de espaços (mesmo um logo após o primeiro ]colchete), com a presença de []colchetes na mensagem de log e com a presença de um aplicativo não marcado. Experimente online!

Como?

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

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

Lê a partir de um arquivo nomeado fe produz em vários arquivos com base na tag.

1 IsmaelMiguel Aug 19 2020 at 19:09

SimpleTemplate 0,84, 109 bytes

Sim, é bem longo, mas funciona!

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

Este código gera um array com <old content>, line, <end of line>.

{@echoS} nivela automaticamente a matriz e a exibe.


Ungolfed:

Sim, é uma bagunça, mas aqui está uma versão mais limpa:

{@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}

A função explodeé uma função PHP padrão, mas acessível na minha linguagem.


Você pode tentar isso em: http://sandbox.onlinephpfunctions.com/code/9c66f8bacc6315ae56e7c193170e430f9cf9d902

1 BlackPanther Aug 18 2020 at 20:56

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

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

Experimente online!

C # (compilador interativo do Visual C #) , 179 bytes

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

Experimente online!

Não tenho certeza se a primeira solução é compatível com code gulf, então a segunda solução usa uma expressão lambda.

1 corvus_192 Aug 20 2020 at 03:43

Haskell, 37 bytes

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

Experimente online!

1 corvus_192 Aug 20 2020 at 03:57

Ferrugem, 40 bytes

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

Faz uma referência mutável a uma fatia de strings e a classifica.

Experimente no parquinho enferrujado

DominicvanEssen Aug 18 2020 at 20:30

Perl 5 -M5.10.0 -Msort = estável, 53 bytes

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

Experimente online!