ログ行のインターリーブ解除[重複]

Aug 18 2020

すべて同じログに出力する複数のアプリを実行するサーバーを継承しました。

あなたの仕事は、ソースごとにログファイルの行をインターリーブ解除することです。幸い、各行は、どのアプリからのものかを示すタグで始まります。

ログ

各行は次のようになります。

[app_name] Something horrible happened!
  • アプリタグは常に角かっこで囲まれ、英数字とアンダースコアのみが含まれます。
  • すべての行の先頭にアプリタグがあります。先行する空白やその他の文字はありません。
  • appタグの後には常に少なくとも1つのスペースがあります
  • アプリのタグは空ではありません
  • 後の任意の行に他の角括弧がある場合があります。
  • タグの後にメッセージがある場合とない場合があります
  • ログが空の可能性があります
  • ファイルに存在する一意のアプリタグの数に制限はありません。

ログ全体は次のようになります。

[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

3つの異なるログを出力する必要があります。

[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

事前にアプリタグの名前が与えられることはありません。ログファイルを分析することによってのみそれらを決定する必要があります。

ルールとスコアリング

  • これはコードゴルフなので、最短のコードが優先されます。
  • 標準のルールと抜け穴が適用されます
  • 各入力行が事前に解析されたタグ+メッセージではなく文字列として表される場合は、任意の便利なIO形式を使用してください。許可された出力の非網羅的なリスト:
    • 各タグにちなんで名付けられたいくつかのファイル
    • 文字列のいくつかのリスト
    • 区切り文字の有無にかかわらず、タグでグループ化された行を含む文字列の1つの連結リスト(区切り文字はタグで始まってはなりません)
    • 上記と同じですが、stdoutまたはファイルになります。
  • 分離されたログが出力される順序は関係ありませんが、各グループ内のログ行は、元のファイルで見つかった順序を保持する必要があります

回答

9 Noodle9 Aug 18 2020 at 03:22

バッシュ、4つの11バイト

Shaggyが親切に指摘したバグを修正するために7バイトを追加しました。

sort -sk1,1

オンラインでお試しください!

空白で区切られsた最初のフィールド(k1,1)に基づいて、安定した並べ替え(コマンドライン引数)を実行します。

7 Giuseppe Aug 18 2020 at 01:35

R、50の46バイト

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

オンラインでお試しください!

list各要素namedを[tag]。とともにaとして出力します。各リスト要素は、タグ内で順序を維持します。named list()空の入力に対して空の名前付きリストを返します。

-ロビンライダーとドミニクファンエッセンのおかげでそれぞれ2バイト!

5 isaacg Aug 18 2020 at 04:48

Pyth、3バイト

ohc

オンラインでお試しください!

入力形式は文字列のリストです。

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

コードの仕組み:

  • o:注文者

  • h:の最初の要素

  • c:各文字列はスペースで分割されます

4 JonathanAllan Aug 18 2020 at 01:55

Python、44バイト

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

オンラインでお試しください!

I / Oが緩い場合は、行のリストを取得して結果を得ることができます。グループを分離する必要がないため、問題は、最初のスペースまでの各行のプレフィックスで安定した並べ替えを実行することになり、split()他の空白文字でも分割されますが、に存在することはできません。アプリケーションタグ部分。

3 Adám Aug 18 2020 at 01:49

APL(Dyalog Extended)、10バイト(SBCS)

匿名の暗黙のプレフィックス関数。文字リストのリストを引数として取ります。各行に1つのログがある、文字リストのマトリックスを返します。

⊢⊢⌸⍨≠⊃⍤⊆¨⊢

オンラインでお試しください!

 議論については、

 非スペースを使用して…

⊆¨ 各リストをリストのリストに分割し(スペースを削除し、非スペースの実行を維持します)、

⊃⍤ 次に、最初の[それぞれの](つまりタグ)を保持します。

⊢⌸⍨ それらをグループ化の鍵として使用してください…

 議論

3 nmjcman101 Aug 18 2020 at 03:14

VIM、13の11バイト

:sor/\w\+/r

@Dingusのおかげでバグ修正とバイトセーブ!

オンラインでお試しください!

3 user Aug 18 2020 at 01:28

Scala、26バイト

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

List[String]間に区切り文字を入れずにを返しますが、タグでソートされます。

Scastieでお試しください


Map[String,List[String]]、26バイトを返します

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

文字列のリストを取得しMap[List[String]]、キーがタグで値がそのタグに関連付けられたログであるaを返します。

Scastieでお試しください


以前のソリューション、66バイト

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

Scastieで試してみてください(何らかの理由で、sTIOでは機能しません)

各アプリのログは2つの改行で区切られます(1つの改行文字である必要がある場合は2バイト節約できる可能性があります)。入力は文字列のリストであり、出力は1つの大きな文字列です。

2 SomoKRoceS Aug 18 2020 at 04:41

05AB1E、3バイト

Σ#¬

入力と出力はログのリストです。

説明:

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

これにより、必要に応じてログの順序も保持されます。

オンラインでお試しください!

2 Neil Aug 18 2020 at 02:27

網膜0.8.2、14の13バイト

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

オンラインでお試しください!説明:出力グループ区切り文字は必要ないため、行はアプリタグで単純にソートされます。これは、一致をキャプチャし、ソートキーとして\w+指定することで実現され$1ます。Retinaでの並べ替えは安定しているため、同じプレフィックスを持つ行は順序を保持します。編集:アプリタグを一致させる簡単な方法を指摘してくれた@FryAmTheEggmanのおかげで1バイト節約できました。一致には先頭のが含まれていませんが[、すべての行がで始まる[ため、並べ替えの結果には影響しないことに注意してください。

2 Noodle9 Aug 18 2020 at 03:42

AWK、62の58バイト

Dominic vanEssenのおかげで4バイト節約できました!!!

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

オンラインでお試しください!

すべての行を2D連想配列に格納しaます。最初のキーは最初のフィールドです(空白で区切られています)。したがって、同じフィールドで始まるすべての行が一緒に格納されます。2番目のキーは、増加する整数インデックスです。最も冗長な部分は、最初のフィールドでグループ化されENDた内容aを出現順に印刷するアクションです。

1 Shaggy Aug 18 2020 at 01:32

Japt、4バイト

入力を行の配列として受け取り、2D配列を出力します。

ü_¸g

それを試してみてください

1 Noname Aug 18 2020 at 07:14

Io、73バイト

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

オンラインでお試しください!

1 JoKing Aug 18 2020 at 21:44

Perl 6、16バイト

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

オンラインでお試しください!

アプリ名である英数字の最初の文字列で並べ替えます

1 DanielH. Aug 18 2020 at 01:11

Pythonの3、148の127バイト

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

オンラインでお試しください!

1 JonathanAllan Aug 19 2020 at 01:02

V(vim)、5バイト

úr/?]

注:?上記は、印刷できないバイトの代わりです\$\text{\x}81\$ (「NoBreakHere」制御文字)。

オンラインでお試しください!

これは、スペースが不足している場合(最初の]ブラケットの直後にある場合でも)、[]ログメッセージにブラケットが存在する場合、およびタグなしアプリケーションが存在する場合に機能することに注意してください。オンラインで試してください。

どうやって?

ú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バイト

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

名前の付いたファイルから読み取りf、タグに基づいて複数のファイルに出力します。

1 IsmaelMiguel Aug 19 2020 at 19:09

SimpleTemplate 0.84、109バイト

ええ、それはかなり長いですが、仕事をします!

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

このコードは、で配列を生成し<old content>, line, <end of line>ます。

{@echoS} 配列を自動的にフラット化して表示します。


ゴルフなし:

はい、それは混乱ですが、ここにもっときれいなバージョンがあります:

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

この関数explodeは標準のPHP関数ですが、私の言語からアクセスできます。


あなたはこれを試すことができます: http://sandbox.onlinephpfunctions.com/code/9c66f8bacc6315ae56e7c193170e430f9cf9d902

1 BlackPanther Aug 18 2020 at 20:56

C#(。NET Core)、 181 162160 バイト

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#(Visual C#インタラクティブコンパイラ)、179バイト

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

オンラインでお試しください!

最初のソリューションがコードガルフに準拠しているかどうかわからないため、2番目のソリューションはラムダ式を使用します。

1 corvus_192 Aug 20 2020 at 03:43

Haskell、37バイト

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

オンラインでお試しください!

1 corvus_192 Aug 20 2020 at 03:57

さび、40バイト

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

文字列のスライスへの可変参照を取得し、それを並べ替えます。

さびた遊び場で試してみてください

DominicvanEssen Aug 18 2020 at 20:30

Perl 5 -M5.10.0 -Msort =安定、53バイト

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

オンラインでお試しください!