ログ行のインターリーブ解除[重複]
すべて同じログに出力する複数のアプリを実行するサーバーを継承しました。
あなたの仕事は、ソースごとにログファイルの行をインターリーブ解除することです。幸い、各行は、どのアプリからのものかを示すタグで始まります。
ログ
各行は次のようになります。
[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またはファイルになります。
- 分離されたログが出力される順序は関係ありませんが、各グループ内のログ行は、元のファイルで見つかった順序を保持する必要があります
回答
バッシュ、4つの11バイト
Shaggyが親切に指摘したバグを修正するために7バイトを追加しました。
sort -sk1,1
オンラインでお試しください!
空白で区切られs
た最初のフィールド(k1,1
)に基づいて、安定した並べ替え(コマンドライン引数)を実行します。
R、50の46バイト
function(r)split(r,substr(r,1,regexpr("]",r)))
オンラインでお試しください!
list
各要素name
dを[tag]
。とともにaとして出力します。各リスト要素は、タグ内で順序を維持します。named list()
空の入力に対して空の名前付きリストを返します。
-ロビンライダーとドミニクファンエッセンのおかげでそれぞれ2バイト!
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
:各文字列はスペースで分割されます
Python、44バイト
lambda a:sorted(a,key=lambda l:l.split()[0])
オンラインでお試しください!
I / Oが緩い場合は、行のリストを取得して結果を得ることができます。グループを分離する必要がないため、問題は、最初のスペースまでの各行のプレフィックスで安定した並べ替えを実行することになり、split()
他の空白文字でも分割されますが、に存在することはできません。アプリケーションタグ部分。
APL(Dyalog Extended)、10バイト(SBCS)
匿名の暗黙のプレフィックス関数。文字リストのリストを引数として取ります。各行に1つのログがある、文字リストのマトリックスを返します。
⊢⊢⌸⍨≠⊃⍤⊆¨⊢
オンラインでお試しください!
⊢
議論については、
≠
非スペースを使用して…
⊆¨
各リストをリストのリストに分割し(スペースを削除し、非スペースの実行を維持します)、
⊃⍤
次に、最初の[それぞれの](つまりタグ)を保持します。
⊢⌸⍨
それらをグループ化の鍵として使用してください…
⊢
議論
VIM、13の11バイト
:sor/\w\+/r
@Dingusのおかげでバグ修正とバイトセーブ!
オンラインでお試しください!
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で試してみてください(何らかの理由で、s
TIOでは機能しません)
各アプリのログは2つの改行で区切られます(1つの改行文字である必要がある場合は2バイト節約できる可能性があります)。入力は文字列のリストであり、出力は1つの大きな文字列です。
05AB1E、3バイト
Σ#¬
入力と出力はログのリストです。
説明:
Σ#¬
Σ Sort by:
# Split (each log) by spaces
¬ Head (which is the tagname)
これにより、必要に応じてログの順序も保持されます。
オンラインでお試しください!
網膜0.8.2、14の13バイト
O$`(\w+).* $1
オンラインでお試しください!説明:出力グループ区切り文字は必要ないため、行はアプリタグで単純にソートされます。これは、一致をキャプチャし、ソートキーとして\w+
指定することで実現され$1
ます。Retinaでの並べ替えは安定しているため、同じプレフィックスを持つ行は順序を保持します。編集:アプリタグを一致させる簡単な方法を指摘してくれた@FryAmTheEggmanのおかげで1バイト節約できました。一致には先頭のが含まれていませんが[
、すべての行がで始まる[
ため、並べ替えの結果には影響しないことに注意してください。
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
を出現順に印刷するアクションです。
Japt、4バイト
入力を行の配列として受け取り、2D配列を出力します。
ü_¸g
それを試してみてください
Io、73バイト
method(i,i map(split first)unique map(I,i select(split first==I))flatten)
オンラインでお試しください!
Perl 6、16バイト
*.sort:{~m/\w+/}
オンラインでお試しください!
アプリ名である英数字の最初の文字列で並べ替えます
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]]
オンラインでお試しください!
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
AutoHotkey、74バイト
Loop,Read,f
{
s:=A_LoopReadLine
FileAppend,%s%`n,% StrSplit(s,"]","[")[1]
}
名前の付いたファイルから読み取りf
、タグに基づいて複数のファイルに出力します。
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
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番目のソリューションはラムダ式を使用します。
Haskell、37バイト
import Data.List
f=sortOn(head.words)
オンラインでお試しください!
さび、40バイト
|a|a.sort_by_key(|x|x.split("]").next())
文字列のスライスへの可変参照を取得し、それを並べ替えます。
さびた遊び場で試してみてください
Perl 5 -M5.10.0 -Msort =安定、53バイト
say sort{(split('\]',$a))[0]cmp(split('\]',$b))[0]}<>
オンラインでお試しください!