Desintercalar líneas de registro [duplicar]
Ha heredado un servidor que ejecuta varias aplicaciones que generan el mismo registro.
Su tarea consiste en desintercalar las líneas del archivo de registro por fuente. Afortunadamente, cada línea comienza con una etiqueta que indica de qué aplicación es.
Registros
Cada línea se verá así:
[app_name] Something horrible happened!
- Las etiquetas de las aplicaciones están siempre entre corchetes y solo contendrán caracteres alfanuméricos y guiones bajos.
- Todas las líneas tendrán una etiqueta de aplicación al principio. No habrá espacios en blanco anteriores ni ningún otro carácter.
- Siempre habrá al menos un espacio después de la etiqueta de la aplicación.
- Las etiquetas de la aplicación no están vacías
- Puede haber otros corchetes más adelante en cualquier línea dada.
- Puede que haya o no un mensaje después de la etiqueta
- El registro puede estar vacío
- No hay límite para la cantidad de etiquetas de aplicaciones únicas que estarán presentes en el archivo.
Ejemplo
Un registro completo podría verse así:
[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 debería generar tres 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
No se le dan los nombres de las etiquetas de la aplicación con anticipación. Debe determinarlos solo analizando el archivo de registro.
Reglas y puntuación
- Esto es code-golf , así que gana el código más corto.
- Se aplican reglas estándar y lagunas
- Utilice cualquier formato de E / S conveniente, siempre que cada línea de entrada esté representada como una cadena, no como una etiqueta + mensaje previamente analizado. Lista no exhaustiva de salidas permitidas:
- Varios archivos nombrados después de cada etiqueta
- Varias listas de cadenas
- Una lista concatenada de cadenas que contienen líneas agrupadas por etiqueta con o sin separador (el separador no debe comenzar con una etiqueta)
- Igual que el anterior, pero para stdout o un archivo.
- El orden en el que se generan los registros separados es irrelevante; sin embargo, las líneas de registro dentro de cada grupo deben conservar el orden en el que se encontraron en el archivo original.
Respuestas
Bash , 4 11 bytes
Se agregaron 7 bytes para corregir un error amablemente señalado por Shaggy .
sort -sk1,1
¡Pruébelo en línea!
Realiza una clasificación estable (el s
argumento de la línea de comandos) basada en el primer campo ( k1,1
) separado por espacios en blanco.
R , 50 46 bytes
function(r)split(r,substr(r,1,regexpr("]",r)))
¡Pruébelo en línea!
Salidas como a list
con cada elemento name
d con [tag]
. Cada elemento de la lista mantiene el orden dentro de su etiqueta. Devuelve una lista con nombre named list()
vacía para una entrada vacía.
-2 bytes cada uno gracias a Robin Ryder y Dominic van Essen.
Pyth , 3 bytes
ohc
¡Pruébelo en línea!
El formato de entrada es una lista de cadenas:
["[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"]
Cómo funciona el código:
o
: Ordenar porh
: El primer elemento dec
: Cada cadena se divide en espacios
Python , 44 bytes
lambda a:sorted(a,key=lambda l:l.split()[0])
¡Pruébelo en línea!
La E / S suelta nos permite tomar y dar como resultado una lista de líneas. Como no tenemos que separar los grupos, el problema se reduce a realizar un tipo estable de las líneas en el prefijo de cada línea hasta el primer espacio, también split()
se dividirán en algunos otros caracteres de espacio en blanco, pero ninguno puede estar presente en la parte de la etiqueta de la aplicación.
APL (Dyalog Extended) , 10 bytes ( SBCS )
Función de prefijo tácito anónimo. Toma una lista de listas de caracteres como argumento. Devuelve una matriz de listas de caracteres, con un registro en cada fila.
⊢⊢⌸⍨≠⊃⍤⊆¨⊢
¡Pruébelo en línea!
⊢
en el argumento,
≠
utilizar los no espacios para ...
⊆¨
dividir cada lista en una lista de listas (elimina espacios, mantiene series de no espacios),
⊃⍤
luego conserve la primera [de cada] (es decir, las etiquetas),
⊢⌸⍨
utilícelos como claves para agrupar ...
⊢
el argumento
vim, 13 11 bytes
:sor/\w\+/r
corrección de errores y ahorro de bytes gracias a @Dingus!
¡Pruébelo en línea!
Scala, 26 bytes
_.sortBy(_.split("]")(0))
Devuelve un List[String]
sin separador en el medio, pero está ordenado por la etiqueta.
Pruébalo en Scastie
Devuelve a Map[String,List[String]]
, 26 bytes
_ groupBy(_.split("]")(0))
Toma una lista de cadenas y devuelve un Map[List[String]]
donde las claves son las etiquetas y los valores son los registros asociados con esa etiqueta.
Pruébalo en Scastie
Solución anterior, 66 bytes
_ groupBy{case s"[$t]$r"=>t}map(_._2 mkString "\n")mkString "\n"*2
Pruébelo en Scastie (por el motivo que sea, s
no funciona en TIO)
Los registros de cada aplicación están separados por 2 líneas nuevas (podría guardar 2 bytes si solo tuviera que ser el carácter de una línea nueva). La entrada es una lista de cadenas y la salida es una cadena grande.
05AB1E , 3 bytes
Σ#¬
Entrada y salida es una lista de registros.
Explicación:
Σ#¬
Σ Sort by:
# Split (each log) by spaces
¬ Head (which is the tagname)
Esto también mantiene el orden de los registros, según sea necesario.
¡Pruébelo en línea!
Retina 0.8.2 , 14 13 bytes
O$`(\w+).* $1
¡Pruébelo en línea! Explicación: Dado que no se requiere un separador de grupos de salida, las líneas simplemente se ordenan por etiqueta de aplicación, lo que se logra capturando la coincidencia \w+
y especificando $1
como clave de clasificación. Ordenar en Retina es estable, por lo que las líneas con el mismo prefijo mantendrán su orden. Editar: Guardado 1 byte gracias a @FryAmTheEggman por señalar una forma más fácil de hacer coincidir la etiqueta de la aplicación. Tenga en cuenta que aunque la coincidencia no incluye el encabezado [
, todas las líneas comienzan con [
, por lo que no afecta el resultado de la clasificación.
AWK , 62 58 bytes
4 bytes guardados gracias a Dominic van Essen !!!
{a[$1][i++]=$0}END{for(k in a)for(j in a[k])print a[k][j]}
¡Pruébelo en línea!
Almacena todas las líneas en una matriz asociativa 2D a
. La primera clave es el primer campo (separado por espacios en blanco). Entonces, todas las líneas que comienzan con el mismo campo se almacenan juntas. La segunda clave es un índice entero creciente. La parte más detallada es la END
acción que imprime el contenido de a
agrupado por primer campo en orden de aparición.
Japonés , 4 bytes
Toma la entrada como una matriz de líneas, genera una matriz 2D.
ü_¸g
Intentalo
Io , 73 bytes
method(i,i map(split first)unique map(I,i select(split first==I))flatten)
Try it online!
Perl 6, 16 bytes
*.sort:{~m/\w+/}
Try it online!
Sorts by the first string of alphanumeric characters, which should be the app name
Python 3, 148127 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]]
Try it online!
V (vim), 5 bytes
úr/?]
Note: The ?
above is in-place of the unprintable byte \$\text{\x}81\$ (the "No Break Here" control character).
Try it online!
Note that this works with a lack of spaces (even one directly after the first ]
bracket), with the presence of []
brackets in the log message, and with the presence of an untagged application, Try it online!
How?
ú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 bytes
Loop,Read,f
{
s:=A_LoopReadLine
FileAppend,%s%`n,% StrSplit(s,"]","[")[1]
}
Reads from a file named f
and outputs into multiple files based on the tag.
SimpleTemplate 0.84, 109 bytes
Yeah, it's pretty long, but does the job!
{@callexplode intoL EOL,argv.0}{@eachL}{@if_ matches"@^(\[.*\])@"M}{@setS.[M.1]S.[M.1],_,EOL}{@/}{@/}{@echoS}
This code generates an array with <old content>, line, <end of line>
.
{@echoS}
automatically flattens the array and displays it.
Ungolfed:
Yes, it's a mess, but here's a cleaner version:
{@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}
The function explode
is a standard PHP function, but accessible from my language.
You can try this on: http://sandbox.onlinephpfunctions.com/code/9c66f8bacc6315ae56e7c193170e430f9cf9d902
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);}});
Try it online!
C# (Visual C# Interactive Compiler), 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);}})
Try it online!
I'm not sure the first solution is code gulf compliant, so the second solution uses a lambda expression.
Haskell, 37 bytes
import Data.List
f=sortOn(head.words)
Try it online!
Rust, 40 bytes
|a|a.sort_by_key(|x|x.split("]").next())
Takes a mutable reference to a slice of strings and sorts it.
Try it on the rust playground
Perl 5 -M5.10.0 -Msort=stable, 53 bytes
say sort{(split('\]',$a))[0]cmp(split('\]',$b))[0]}<>
Try it online!