gping, tealdeer, column を試してみた。

こんにちは。今週も Github にて見つけた repository で遊んでいきます。

gping

ping ではなく、gping。グラフィカルな ping を提供してくれるとのこと。 https://github.com/orf/gping

適当に google.com で試してみる。

~ brew install gping
~ gping google.com

ping の response time を グラフにして表示しているんですかね....。なぜこんなもんを...笑。

f:id:K-jun1221:20210626182522p:plain

tealdeer

tldr という少し前に出てきた、拡張版 man のようなものの rust での実装みたいですね。

~ brew install tealdeer
~ tldr --update

sed, rsync, awk, ln などコマンドの利用方法を忘れがちなのでありがたいですね。

~ tldr sed

  Edit text in a scriptable manner.
  More information: <https://ss64.com/osx/sed.html>.

  Replace the first occurrence of a string in a file, and print the result:

      sed 's/find/replace/' filename

  Replace all occurrences of an extended regular expression in a file:

      sed -E 's/regular_expression/replace/g' filename

  Replace all occurrences of a string [i]n a file, overwriting the file (i.e. in-place):

      sed -i '' 's/find/replace/g' filename

  Replace only on lines matching the line pattern:

      sed '/line_pattern/s/find/replace/' filename

  Print only text between n-th line till the next empty line:

      sed -n 'line_number,/^$/p' filename

  Apply multiple find-replace expressions to a file:

      sed -e 's/find/replace/' -e 's/find/replace/' filename

  Replace separator / by any other character not used in the find or replace patterns, e.g., #:

      sed 's#find#replace#' filename

  [d]elete the line at the specific line number [i]n a file, overwriting the file:

      sed -i '' 'line_numberd' filename

~ tldr ln

  Creates links to files and directories.
  More information: <https://www.gnu.org/software/coreutils/ln>.

  Create a symbolic link to a file or directory:

      ln -s /path/to/file_or_directory path/to/symlink

  Overwrite an existing symbolic link to point to a different file:

      ln -sf /path/to/new_file path/to/symlink

  Create a hard link to a file:

      ln /path/to/file path/to/hardlink

column

Redis のような in-memory database。内部の構造がどのようになっているところまでは見ていないが、こういうデータベース系統は総じて面白い。

https://github.com/kelindar/column

インストールして使ってみる。

~ go get github.com/kelindar/column

map[string]interface{} の型しか受けつけていないのは少し残念。golang と紐付いている in-memory database なので型の恩恵を受けられると良かった。 import 用のデータを json で定義しておく。

[
    {"title": "officia", "body": "Nemo est aut magnam provident accusantium. Architecto omnis error excepturi voluptatum delectus. Quos velit corporis ducimus sit rerum sint voluptatem.", "done": false},
    {"title": "sed", "body": "Ipsam autem possimus delectus laborum sint. Saepe suscipit ab unde magni voluptas quas et. Ut dolores similique commodi ut distinctio.", "done": true},
    {"title": "asperiores", "body": "Nulla voluptates qui autem aut sint. Sit dolores laboriosam expedita et sunt.", "done": false}
]

ひとまず column を定義してデータを insert して取り出すまで。

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "os"

    "github.com/kelindar/column"
)

func main() {
    todos := []map[string]interface{}{}
    fh, err := os.Open("./todo.json")
    if err != nil {
        log.Fatal(err)
    }
    bytes, err := ioutil.ReadAll(fh)
    if err != nil {
        log.Fatal(err)
    }
    err = json.Unmarshal(bytes, &todos)
    if err != nil {
        log.Fatal(err)
    }
    db := column.NewCollection()
    db.CreateColumnsOf(todos[0])
    for _, v := range todos {
        db.Insert(v)
    }

    // query
    db.Query(func(txn *column.Txn) error {
        count := txn.WithValue("done", func(v interface{}) bool {
            return v == true
        }).Count()
        fmt.Println("todo amount(done == true):", count)
        return nil
    })
}
~ go run main.go
todo amount(done == true): 1

おおお、いけてそう。index もつけられるみたいなので、作成して、更新。その後 index を利用した query によって index が更新されていることまで確認してみる。

...
    // create index
    db.CreateIndex("ok", "done", func(v interface{}) bool {
        return v == true
    })
    db.CreateIndex("ng", "done", func(v interface{}) bool {
        return v == false
    })
    db.Query(func(txn *column.Txn) error {
        txn.With("ng").Select(func(v column.Selector) bool {
            fmt.Println("todo (done == false):", v.StringAt("title"))
            return true
        })
        return nil
    })

    // update
    db.Query(func(txn *column.Txn) error {
        txn.With("ng").Range("done", func(v column.Cursor) bool {
            v.Update(true)                                        // Update the "balance" to 10.0
            v.UpdateAt("title", v.StringAt("title")+"(finished)") // Update the "age" to 50
            return true
        }) // Select the balance
        return nil
    })
    db.Query(func(txn *column.Txn) error {
        txn.With("ok").Select(func(v column.Selector) bool {
            fmt.Println("todo (done == true):", v.StringAt("title"))
            return true
        })
        return nil
    })
...
~ go run main.go
todo (done == false): officia
todo (done == false): asperiores
todo (done == true): officia(finished)
todo (done == true): sed
todo (done == true): asperiores(finished)

大丈夫そう。redis と違ってて面白いなぁ。作成の動機が知りたい笑 それでは今週はこのへんで。