{"id":363260,"date":"2024-05-21T01:52:13","date_gmt":"2024-05-21T01:52:13","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=363260"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-05-21T01:52:13","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=363260","title":{"rendered":"<span>Automate the boring stuff with Julia<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>Into<\/h3>\n<p>\u0421\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e Julia \u2013 \u044d\u0442\u043e \u043d\u0438\u0448\u0435\u0432\u044b\u0439 \u044f\u0437\u044b\u043a \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0434\u043b\u044f \u043b\u0430\u0431\u043e\u0440\u0430\u0442\u043e\u0440\u0438\u0439, \u043d\u0430\u0443\u0447\u043d\u044b\u0445 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0439 \u0438 HPC.<br \/> \u0425\u043e\u0442\u044f \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u0432\u043e\u0439 \u044d\u043a\u0441\u043f\u0440\u0435\u0441\u0441\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u0438 \u0434\u0438\u043d\u0430\u043c\u0438\u0437\u043c\u0443 Julia \u043c\u043e\u0436\u043d\u043e \u0438 \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u0438\u043d\u0433\u0430.<br \/> \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430 \u043f\u0430\u0440\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u043a Julia \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0440\u0443\u0442\u0438\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447.<\/p>\n<h3>Ad-hoc analytics<\/h3>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Julia \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0435 \u0434\u043b\u044f \u041f\u0438\u0442\u043e\u043d\u0438\u0441\u0442\u043e\u0432 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b.<br \/> \u0412\u043c\u0435\u0441\u0442\u043e kaggle, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0434\u0430\u0442\u0430-\u0441\u0435\u0442.<br \/> \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0443\u0442\u0438\u043b\u0438\u0442: git \u0438 jq.<\/p>\n<p>Centos:<\/p>\n<pre><code>yum install epel-release -y yum install jq <\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043a\u043b\u043e\u043d\u0438\u0440\u0443\u0435\u043c \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439:<\/p>\n<pre><code>julia> run(`git clone https:\/\/github.com\/freebsd\/freebsd-src.git`)  julia> cd(\"freebsd-src\/\") <\/code><\/pre>\n<p>\u0423 FreeBSD \u0434\u043e\u043b\u0433\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0438 \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u0442\u044b\u0441\u044f\u0447 \u043a\u043e\u043c\u043c\u0438\u0442\u0435\u0440\u043e\u0432. \u0410\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043b\u043e\u0433-\u0444\u0430\u0439\u043b (\u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 170\u041c\u0431) \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e grep \u0438 AWK \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e,<br \/> \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u043a\u043e\u043c\u043c\u0438\u0442\u043e\u0432 \u0432 JSON.<\/p>\n<pre><code class=\"julia\">cmd = `git log --all --pretty=format:\"%h%x09%an%x09%ad%x09%s\" --date=short --no-merges` cmd1 = `jq -R '[ inputs | split(\"\\t\") | { hash: .[0], author: .[1], date: .[2], message: .[3] }]'`  try     redirect_stdio(stdout=\"repo.json\") do       run(pipeline(cmd, cmd1))     end catch err     Pkg.Types.pkgerror(\"The command $(cmd) '|' $(cmd1) failed, error: $err\") end <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 repo.json \u0432 DataFrames \u2013 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u0443\u044e \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u043e\u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0430\u043d\u043d\u044b\u0445.<br \/> \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u044b DataFrames \u0438 JSON3.<\/p>\n<pre><code>julia> using DataFrames, JSON3 <\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e-\u043f\u043e\u043c\u043e\u0449\u043d\u0438\u043a \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f JSON:<\/p>\n<pre><code class=\"julia\">function read_json(file)            open(file,\"r\") do f                return JSON.parse(f)            end        end <\/code><\/pre>\n<p>\u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 \u0432 Data Frame:<\/p>\n<pre><code>julia> df = DataFrame(read_json(\"repo.json\")) <\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u043a\u0441\u0442\u0430\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432 \u2013 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0447\u0435\u043c \u0432 Python:<\/p>\n<pre><code>julia> @time df = DataFrame(read_json(\"repo.json\"))   29.901792 seconds (49.18 M allocations: 2.809 GiB, 14.31% gc time) <\/code><\/pre>\n<p>\u041e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c DataFrame \u043f\u043e \u0434\u0430\u0442\u0435:<\/p>\n<pre><code>julia> sort!(df, [order(:date, rev=true)]) <\/code><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/post_images\/0cd\/0b6\/359\/0cd0b6359e9afecb32737601a2a59e27.jpg\" alt=\"sort.png\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/0cd\/0b6\/359\/0cd0b6359e9afecb32737601a2a59e27.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>sort.png<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u0430\u043a \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u043c\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e \u0432 \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0435? \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u043c\u044f \u0430\u0432\u0442\u043e\u0440\u0430 \u043a\u043e\u043c\u043c\u0438\u0442\u0430:<\/p>\n<pre><code>julia> gdf = groupby(df, :author) julia> gdf[(\"Jessica Clarke\",)] <\/code><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/post_images\/983\/95a\/7ec\/98395a7ec9c57233355b512f7c5258aa.jpg\" alt=\"groupby\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/983\/95a\/7ec\/98395a7ec9c57233355b512f7c5258aa.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>groupby<\/figcaption><\/div>\n<\/figure>\n<h3>Scripting<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0434\u043b\u044f git-hooks, CI\/CD, \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0433\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0442\u043e Julia \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439.<br \/> \u041a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0438 REPL \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0438 \u0441\u043a\u043b\u0435\u0438\u0432\u0430\u0442\u044c \u0432\u044b\u0432\u043e\u0434 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0443\u0442\u0438\u043b\u0438\u0442 \u043d\u0435 \u0445\u0443\u0436\u0435 \u0447\u0435\u043c \u043d\u0430 Bash:<\/p>\n<pre><code class=\"julia\">#!\/usr\/bin\/env julia  if isdir(\".git\") println   @info(\"== Remote Branches: \")   run(`git branch -r`)      @info(\"== Local Branches:  \")   run(`git branch`)      @info(\"== Configuration (.git\/config)\")   run(`cat .git\/config`)      @info(\"== Most Recent Commit:  \")   run(` git --no-pager log --max-count=1`)      @info(\"== Most Recent Commit:  \")   run(`git log --pretty=format:\"-> %s\" --before=today -10`) else   println(\"Not a git repository.\") end <\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u0441\u043a\u0440\u0438\u043f\u0442:<\/p>\n<pre><code>chmod +x git-info.jl .\/git-info.jl <\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 Git, \u043d\u043e \u0435\u0441\u043b\u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u0442\u043e \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 Bash,<br \/> \u043d\u0430 Julia \u0435\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u2013 ArgParse.jl.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/post_images\/57f\/20d\/cb9\/57f20dcb94b01fc178a79c044758791e.jpg\" alt=\"git-info\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/57f\/20d\/cb9\/57f20dcb94b01fc178a79c044758791e.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>git-info<\/figcaption><\/div>\n<\/figure>\n<h3>Pluto &amp; CSV<\/h3>\n<p><a href=\"https:\/\/plutojl.org\" rel=\"noopener noreferrer nofollow\">Pluto.jl<\/a> \u2013 \u044d\u0442\u043e Jupyter notebook, \u0434\u043b\u044f Julia. \u041f\u043e\u043a\u0430 \u043e\u043d \u0443\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u043f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c \u0438  \u0432 &#171;\u043e\u0442\u043f\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0441\u0442\u0438&#187; Jupyter, \u043d\u043e \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f.<br \/> \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Pluto \u0432 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435:<\/p>\n<pre><code>julia> using Pluto <\/code><\/pre>\n<p>\u041d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c web Ui Pluto:<\/p>\n<pre><code>julia> Pluto.run(host=\"0.0.0.0\", port=11234)  [ Info: Loading... \u250c Info: \u2514 Go to http:\/\/0.0.0.0:11234\/?secret=coDN9HGC in your browser to start writing ~ have fun! \u250c Info: \u2502 Press Ctrl+C in this terminal to stop Pluto <\/code><\/pre>\n<p>\u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u0430\u0434\u0440\u0435\u0441 (http:\/\/IP_ADDR:11234\/?secret=coDN9HGC) \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0438 \u043f\u043e\u043c\u0435\u043d\u044f\u0439\u0442\u0435 IP \u0430\u0434\u0440\u0435\u0441.<\/p>\n<p>\u0412 \u043d\u043e\u0443\u0442\u0431\u0443\u043a\u0435 \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u044f\u0447\u0435\u0439\u043a\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u044b DataFrames, CSV:<\/p>\n<pre><code>julia> using CSV, DataFrames <\/code><\/pre>\n<p>Sadf \u0438 sar \u2013 \u044d\u0442\u043e \u0434\u0432\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432 \u043f\u0430\u043a\u0435\u0442 <a href=\"https:\/\/www.influxdata.com\/integration\/sysstat\" rel=\"noopener noreferrer nofollow\">Sysstat<\/a> \u2013 \u0434\u0435\u043c\u043e\u043d \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430,<br \/> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0438 \u0441\u0431\u043e\u0440\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u043c\u0435\u0442\u0440\u0438\u043a. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0434\u0430\u0442\u0430-\u0441\u0435\u0442\u0430:<\/p>\n<pre><code>julia> df = DataFrame(CSV.File(`sadf -d \/var\/log\/sa\/sa16 -- -dp`)) <\/code><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/post_images\/1c3\/266\/a36\/1c3266a36150a59904c455b85eee0239.jpg\" alt=\"sar\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/1c3\/266\/a36\/1c3266a36150a59904c455b85eee0239.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>sar<\/figcaption><\/div>\n<\/figure>\n<p>\u041c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u043c \u0434\u0430\u0442\u0430-\u0441\u0435\u0442\u0435:<\/p>\n<pre><code>julia> DataFrames.describe(df) <\/code><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/post_images\/3d9\/01e\/37b\/3d901e37b38e48dc0864a89fe0b00c2e.jpg\" alt=\"describe\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/3d9\/01e\/37b\/3d901e37b38e48dc0864a89fe0b00c2e.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>describe<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u043e \u0443\u0442\u0438\u043b\u0438\u0437\u0430\u0446\u0438\u0438:<\/p>\n<pre><code>julia> sort!(df, [order(\"%util\", rev=true), :\"DEV\"]) <\/code><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/post_images\/3d8\/803\/c4b\/3d8803c4bf1fd7ad5c4cda00102f0efa.jpg\" alt=\"sort\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/3d8\/803\/c4b\/3d8803c4bf1fd7ad5c4cda00102f0efa.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>sort<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0432\u044b\u0432\u043e\u0434\u0430 sar \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 grep, sed \u0438 AWK, \u0430 \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c Prometheus \u0438 Grafana. \u041d\u043e \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u00ab\u0441\u043a\u043b\u0435\u0438\u0442\u044c\u00bb \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e join \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u0434\u0430\u0442\u0430-\u0441\u0435\u0442\u043e\u0432 (\u0442\u0430\u0431\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u043d\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043b\u043e\u0433\u0438) \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0433\u0440\u0430\u0444\u0438\u043a\u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u043e \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 Julia:<\/p>\n<pre><code>julia> j =  JSON3.read(`journalctl -k -b -o json-pretty`, jsonlines=true)  julia> df = DataFrame(j)  julia> select(df5, Not([:__CURSOR, :__REALTIME_TIMESTAMP, :__MONOTONIC_TIMESTAMP, :_BOOT_ID, :_MACHINE_ID, :_SOURCE_MONOTONIC_TIMESTAMP])) <\/code><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/post_images\/27f\/c77\/098\/27fc77098cd9ae3bfec6633ffe03f75e.jpg\" alt=\"log\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/27f\/c77\/098\/27fc77098cd9ae3bfec6633ffe03f75e.jpg\" data-blurred=\"true\"\/><\/p>\n<div><figcaption>log<\/figcaption><\/div>\n<\/figure>\n<h3>End<\/h3>\n<p>\u0410\u0432\u0442\u043e\u0440\u044b Julia \u0432 \u0441\u0432\u043e\u0435\u043c \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0435 <a href=\"https:\/\/julialang.org\/blog\/2012\/02\/why-we-created-julia\" rel=\"noopener noreferrer nofollow\">Why We Created Julia<\/a> \u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0434 \u0441\u043e\u0431\u043e\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0446\u0435\u043b\u0438:<\/p>\n<p><em>&#171;We want something as usable for general programming as Python, as easy for statistics as R, as natural for string processing as Perl, as powerful for linear algebra as Matlab, as good at gluing programs together as the shell. Something that is dirt simple to learn, yet keeps the most serious hackers happy. We want it interactive and we want it compiled.&#187;<\/em><\/p>\n<p>\u041d\u0435 \u0432\u0441\u0435 \u0438\u0437 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u043d\u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0432\u043e\u043f\u043b\u043e\u0442\u0438\u0442\u044c \u0432 \u0436\u0438\u0437\u043d\u044c, Julia \u043d\u0435 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u0430. \u041f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f Lisp, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0437\u044f\u043b \u0432\u0441\u0435 \u043b\u0443\u0447\u0448\u0435\u0435 \u0443 Python (<code>julia --lisp<\/code>).<br \/> \u042f\u0437\u044b\u043a \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0432\u044b \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u043d\u0430 \u043d\u0435\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u0438\u0441\u0430\u043b\u0438.<\/p>\n<p>PS. \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u044d\u0442\u043e \u0441\u0442\u0430\u043d\u0435\u0442 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u00abAutomate the boring stuff with Julia\u00bb \ud83d\ude42<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/781422\/\"> https:\/\/habr.com\/ru\/articles\/781422\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>Into<\/h3>\n<p>\u0421\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e Julia \u2013 \u044d\u0442\u043e \u043d\u0438\u0448\u0435\u0432\u044b\u0439 \u044f\u0437\u044b\u043a \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0434\u043b\u044f \u043b\u0430\u0431\u043e\u0440\u0430\u0442\u043e\u0440\u0438\u0439, \u043d\u0430\u0443\u0447\u043d\u044b\u0445 \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u0439 \u0438 HPC.<br \/> \u0425\u043e\u0442\u044f \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u0432\u043e\u0439 \u044d\u043a\u0441\u043f\u0440\u0435\u0441\u0441\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u0438 \u0434\u0438\u043d\u0430\u043c\u0438\u0437\u043c\u0443 Julia \u043c\u043e\u0436\u043d\u043e \u0438 \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u0438\u043d\u0433\u0430.<br \/> \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430 \u043f\u0430\u0440\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u043a Julia \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0440\u0443\u0442\u0438\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447.<\/p>\n<h3>Ad-hoc analytics<\/h3>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Julia \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u0435 \u0434\u043b\u044f \u041f\u0438\u0442\u043e\u043d\u0438\u0441\u0442\u043e\u0432 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b.<br \/> \u0412\u043c\u0435\u0441\u0442\u043e kaggle, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0434\u0430\u0442\u0430-\u0441\u0435\u0442.<br \/> \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0443\u0442\u0438\u043b\u0438\u0442: git \u0438 jq.<\/p>\n<p>Centos:<\/p>\n<pre><code>yum install epel-release -y yum install jq <\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043a\u043b\u043e\u043d\u0438\u0440\u0443\u0435\u043c \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439:<\/p>\n<pre><code>julia> run(`git clone https:\/\/github.com\/freebsd\/freebsd-src.git`)  julia> cd(\"freebsd-src\/\") <\/code><\/pre>\n<p>\u0423 FreeBSD \u0434\u043e\u043b\u0433\u0430\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0438 \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u0442\u044b\u0441\u044f\u0447 \u043a\u043e\u043c\u043c\u0438\u0442\u0435\u0440\u043e\u0432. \u0410\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043b\u043e\u0433-\u0444\u0430\u0439\u043b (\u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 170\u041c\u0431) \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e grep \u0438 AWK \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e,<br \/> \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u043a\u043e\u043c\u043c\u0438\u0442\u043e\u0432 \u0432 JSON.<\/p>\n<pre><code class=\"julia\">cmd = `git log --all --pretty=format:\"%h%x09%an%x09%ad%x09%s\" --date=short --no-merges` cmd1 = `jq -R '[ inputs | split(\"\\t\") | { hash: .[0], author: .[1], date: .[2], message: .[3] }]'`  try     redirect_stdio(stdout=\"repo.json\") do       run(pipeline(cmd, cmd1))     end catch err     Pkg.Types.pkgerror(\"The command $(cmd) '|' $(cmd1) failed, error: $err\") end <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 repo.json \u0432 DataFrames \u2013 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u0443\u044e \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u043e\u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0430\u043d\u043d\u044b\u0445.<br \/> \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u044b DataFrames \u0438 JSON3.<\/p>\n<pre><code>julia> using DataFrames, JSON3 <\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e-\u043f\u043e\u043c\u043e\u0449\u043d\u0438\u043a \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f JSON:<\/p>\n<pre><code class=\"julia\">function read_json(file)            open(file,\"r\") do f                return JSON.parse(f)            end        end <\/code><\/pre>\n<p>\u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 \u0432 Data Frame:<\/p>\n<pre><code>julia> df = DataFrame(read_json(\"repo.json\")) <\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u043a\u0441\u0442\u0430\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432 \u2013 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0447\u0435\u043c \u0432 Python:<\/p>\n<pre><code>julia> @time df = DataFrame(read_json(\"repo.json\"))   29.901792 seconds (49.18 M allocations: 2.809 GiB, 14.31% gc time) <\/code><\/pre>\n<p>\u041e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c DataFrame \u043f\u043e \u0434\u0430\u0442\u0435:<\/p>\n<pre><code>julia> sort!(df, [order(:date, rev=true)]) <\/code><\/pre>\n<figure class=\"\">\n<div><figcaption>sort.png<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u0430\u043a \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u043c\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e \u0432 \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0435? \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u043c\u044f \u0430\u0432\u0442\u043e\u0440\u0430 \u043a\u043e\u043c\u043c\u0438\u0442\u0430:<\/p>\n<pre><code>julia> gdf = groupby(df, :author) julia> gdf[(\"Jessica Clarke\",)] <\/code><\/pre>\n<figure class=\"\">\n<div><figcaption>groupby<\/figcaption><\/div>\n<\/figure>\n<h3>Scripting<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0434\u043b\u044f git-hooks, CI\/CD, \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u043e\u0433\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0442\u043e Julia \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439.<br \/> \u041a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u044b\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0438 REPL \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0438 \u0441\u043a\u043b\u0435\u0438\u0432\u0430\u0442\u044c \u0432\u044b\u0432\u043e\u0434 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0443\u0442\u0438\u043b\u0438\u0442 \u043d\u0435 \u0445\u0443\u0436\u0435 \u0447\u0435\u043c \u043d\u0430 Bash:<\/p>\n<pre><code class=\"julia\">#!\/usr\/bin\/env julia  if isdir(\".git\") println   @info(\"== Remote Branches: \")   run(`git branch -r`)      @info(\"== Local Branches:  \")   run(`git branch`)      @info(\"== Configuration (.git\/config)\")   run(`cat .git\/config`)      @info(\"== Most Recent Commit:  \")   run(` git --no-pager log --max-count=1`)      @info(\"== Most Recent Commit:  \")   run(`git log --pretty=format:\"-> %s\" --before=today -10`) else   println(\"Not a git repository.\") end <\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043c \u0441\u043a\u0440\u0438\u043f\u0442:<\/p>\n<pre><code>chmod +x git-info.jl .\/git-info.jl <\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 Git, \u043d\u043e \u0435\u0441\u043b\u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u0442\u043e \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 Bash,<br \/> \u043d\u0430 Julia \u0435\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u2013 ArgParse.jl.<\/p>\n<figure class=\"\">\n<div><figcaption>git-info<\/figcaption><\/div>\n<\/figure>\n<h3>Pluto &amp; CSV<\/h3>\n<p><a href=\"https:\/\/plutojl.org\" rel=\"noopener noreferrer nofollow\">Pluto.jl<\/a> \u2013 \u044d\u0442\u043e Jupyter notebook, \u0434\u043b\u044f Julia. \u041f\u043e\u043a\u0430 \u043e\u043d \u0443\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u043f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c \u0438  \u0432 &#171;\u043e\u0442\u043f\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0441\u0442\u0438&#187; Jupyter, \u043d\u043e \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044f.<br \/> \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Pluto \u0432 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435:<\/p>\n<pre><code>julia> using Pluto <\/code><\/pre>\n<p>\u041d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c web Ui Pluto:<\/p>\n<pre><code>julia> Pluto.run(host=\"0.0.0.0\", port=11234)  [ Info: Loading... \u250c Info: \u2514 Go to http:\/\/0.0.0.0:11234\/?secret=coDN9HGC in your browser to start writing ~ have fun! \u250c Info: \u2502 Press Ctrl+C in this terminal to stop Pluto <\/code><\/pre>\n<p>\u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u0430\u0434\u0440\u0435\u0441 (http:\/\/IP_ADDR:11234\/?secret=coDN9HGC) \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0438 \u043f\u043e\u043c\u0435\u043d\u044f\u0439\u0442\u0435 IP \u0430\u0434\u0440\u0435\u0441.<\/p>\n<p>\u0412 \u043d\u043e\u0443\u0442\u0431\u0443\u043a\u0435 \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u044f\u0447\u0435\u0439\u043a\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043f\u0430\u043a\u0435\u0442\u044b DataFrames, CSV:<\/p>\n<pre><code>julia> using CSV, DataFrames <\/code><\/pre>\n<p>Sadf \u0438 sar \u2013 \u044d\u0442\u043e \u0434\u0432\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0445\u043e\u0434\u044f\u0442 \u0432 \u043f\u0430\u043a\u0435\u0442 <a href=\"https:\/\/www.influxdata.com\/integration\/sysstat\" rel=\"noopener noreferrer nofollow\">Sysstat<\/a> \u2013 \u0434\u0435\u043c\u043e\u043d \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430,<br \/> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0438 \u0441\u0431\u043e\u0440\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u043c\u0435\u0442\u0440\u0438\u043a. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0434\u0430\u0442\u0430-\u0441\u0435\u0442\u0430:<\/p>\n<pre><code>julia> df = DataFrame(CSV.File(`sadf -d \/var\/log\/sa\/sa16 -- -dp`)) <\/code><\/pre>\n<figure class=\"\">\n<div><figcaption>sar<\/figcaption><\/div>\n<\/figure>\n<p>\u041c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u043c \u0434\u0430\u0442\u0430-\u0441\u0435\u0442\u0435:<\/p>\n<pre><code>julia> DataFrames.describe(df) <\/code><\/pre>\n<figure class=\"\">\n<div><figcaption>describe<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u043e \u0443\u0442\u0438\u043b\u0438\u0437\u0430\u0446\u0438\u0438:<\/p>\n<pre><code>julia> sort!(df, [order(\"%util\", rev=true), :\"DEV\"]) <\/code><\/pre>\n<figure class=\"\">\n<div><figcaption>sort<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0432\u044b\u0432\u043e\u0434\u0430 sar \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 grep, sed \u0438 AWK, \u0430 \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c Prometheus \u0438 Grafana. \u041d\u043e \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u00ab\u0441\u043a\u043b\u0435\u0438\u0442\u044c\u00bb \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e join \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u0434\u0430\u0442\u0430-\u0441\u0435\u0442\u043e\u0432 (\u0442\u0430\u0431\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u043d\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043b\u043e\u0433\u0438) \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0433\u0440\u0430\u0444\u0438\u043a\u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u043e \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442 Julia:<\/p>\n<pre><code>julia> j =  JSON3.read(`journalctl -k -b -o json-pretty`, jsonlines=true)  julia> df = DataFrame(j)  julia> select(df5, Not([:__CURSOR, :__REALTIME_TIMESTAMP, :__MONOTONIC_TIMESTAMP, :_BOOT_ID, :_MACHINE_ID, :_SOURCE_MONOTONIC_TIMESTAMP])) <\/code><\/pre>\n<figure class=\"\">\n<div><figcaption>log<\/figcaption><\/div>\n<\/figure>\n<h3>End<\/h3>\n<p>\u0410\u0432\u0442\u043e\u0440\u044b Julia \u0432 \u0441\u0432\u043e\u0435\u043c \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0435 <a href=\"https:\/\/julialang.org\/blog\/2012\/02\/why-we-created-julia\" rel=\"noopener noreferrer nofollow\">Why We Created Julia<\/a> \u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0434 \u0441\u043e\u0431\u043e\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0446\u0435\u043b\u0438:<\/p>\n<p><em>&#171;We want something as usable for general programming as Python, as easy for statistics as R, as natural for string processing as Perl, as powerful for linear algebra as Matlab, as good at gluing programs together as the shell. Something that is dirt simple to learn, yet keeps the most serious hackers happy. We want it interactive and we want it compiled.&#187;<\/em><\/p>\n<p>\u041d\u0435 \u0432\u0441\u0435 \u0438\u0437 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043e\u043d\u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0432\u043e\u043f\u043b\u043e\u0442\u0438\u0442\u044c \u0432 \u0436\u0438\u0437\u043d\u044c, Julia \u043d\u0435 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u0430. \u041f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f Lisp, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0437\u044f\u043b \u0432\u0441\u0435 \u043b\u0443\u0447\u0448\u0435\u0435 \u0443 Python (<code>julia --lisp<\/code>).<br \/> \u042f\u0437\u044b\u043a \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0432\u044b \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u043d\u0430 \u043d\u0435\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u0438\u0441\u0430\u043b\u0438.<\/p>\n<p>PS. \u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u044d\u0442\u043e \u0441\u0442\u0430\u043d\u0435\u0442 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u00abAutomate the boring stuff with Julia\u00bb \ud83d\ude42<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/781422\/\"> https:\/\/habr.com\/ru\/articles\/781422\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-363260","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/363260","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=363260"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/363260\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=363260"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=363260"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=363260"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}