コマンドプロンプトで関数を定義する・バッチ処理に引数(パラメータ)を指定する

久しぶりにbatファイルで作業をする機会があったので、メモとして記載します。

コマンドプロンプトで関数を定義するバッチスクリプト

@echo off
setlocal

echo Start ERRORLEVEL : %ERRORLEVEL%
Call :sampleFunc %1
echo End   ERRORLEVEL : %ERRORLEVEL%

endlocal
exit /b

:sampleFunc
echo Sample Fucntion Call %1
exit /b 777

関数は11行目以降です。”:”(コロン)の後に関数名を定義します。echo で”Sample Fucntion Call”+引数 を出力して、終了コード”777″で関数の処理を終了します。

5行目の、”Call :関数名 %1″で関数を呼び出します。”%1″はこのバッチスクリプトの1つ目の引数に指定された値が設定されます。

関数以外のバッチスクリプト自体は、以下の流れとなります。

  • ERRORLEVELの出力
  • 関数”sampleFunc”に”%1″を渡して呼び出し
  • ERRORLEVELの出力

実行結果

上記のバッチスクリプトを”func.exe”で保存した場合の実行例です。

“param1″と”123″を指定して2回実行しています。”echo %ERRORLEVEL%”で、バッチスクリプトの終了コードを表示します。

C:\Dev>func.bat param1
Start ERRORLEVEL : 0
Sample Fucntion Call param1
End   ERRORLEVEL : 777

C:\Dev>echo %ERRORLEVEL%
777

C:\Dev>func.bat 123
Start ERRORLEVEL : 0
Sample Fucntion Call 123
End   ERRORLEVEL : 777

C:\Dev>echo %ERRORLEVEL%
777

C:\Dev>

正規表現の基本的な書き方

正規表現の基本的な書き方一覧。よく忘れるのでメモとして記載します。

正規表現の書き方マッチする文字
abcabc
abc|aecabc, aec
a(b|e)cabc, aec
a[be]c abc, aec
a[abcde]caac, abc, acc, adc, aec
a[a-e]caac, abc, acc, adc, aec
a[a-cX-Z]caac, abc, acc, aXc, aYc, aZc
abcd?eabce, abcde
abcd+eabcde, abcdde, abcddde, …
abcd*eabce, abcde, abcdde, abcddde, …
a{2}aa
a{2}b{4}aabbbb
a{2,}aa, aaa, aaaa, aaaaa, …
a{2,4}aa, aaa, aaaa
[0-9]0, 1, 2, 3, 4, 5, 6, 7, 8, 9(数値のみ)
[1-36-9]1, 2, 3, 6, 7, 8, 9
\d0, 1, 2, 3, 4, 5, 6, 7, 8, 9(数値のみ)
\D数値以外
[^0-9]数値以外([](カッコ)内先頭の^(キャレット)は否定)
[^\D]数値のみ(数値以外の否定は数値のみ)
0[89]0-\d{4}-\d{4}  携帯番号(080-xxxx-xxxx, 090-xxxx-xxxx)  
^abc行の先頭のabc
abc$行の末尾のabc
^abc$abcだけの行(行の先頭も行の末尾もabc)


正規表現 基本的な書き方解説

上記の内容をざっくり解説します。

abc|aec

“|”(パイプ)で挟むと または(OR) 指定できる。abc, aec にマッチする。

a(b|e)c

“()”(かっこ)内の文字を”|”で挟むと または(OR) 指定できる。abc, aec にマッチする。

a[be]c

“[]”(角かっこ)内の文字を または(OR) 指定できる。角カッコの場合、パイプを挟む必要はない。abc, aec にマッチする。

a[abcde]c

ひとつ上の正規表現の文字数を増やした正規表現。 aac, abc, acc, adc, aec にマッチする。

a[a-e]c

“[]”内でハイフンで文字や数値を指定すると範囲指定できる。上記は、”a” から “e” までの小文字の文字列を指定している。aac, abc, acc, adc, aec にマッチする。

a[a-cX-Z]c

上記正規表現の範囲指定を2つ指定している正規表現。”a” から “c” の小文字、 “X” から “Z” の大文字を指定している。 aac, abc, acc, aXc, aYc, aZc にマッチする。

abcd?e

対象文字の後に、”?”(クエスチョンマーク)を指定すると、 1文字あるまたはなくても、つまり 0回 または 1回 文字があれば、マッチする。上記の場合、dがあってもなくてもマッチするため、 abce, abcde にマッチする。

abcd+e

対象文字の後に、”+”(プラス)を指定すると、対象文字が1文字以上連続してあれば、つまり 1回以上 文字があればマッチする。上記の場合、dが1文字以上あればマッチするため、 abcde, abcdde, abcddde, … にマッチする。

abcd*e

対象文字のあとに、”*”(アスタリスク)を指定すると、対象文字が1文字以上連続してあるまたはなくても、つまり 0回 または 1回以上 文字があればマッチする。上記の場合、abce, abcde, abcdde, abcddde, … にマッチする。

a{2}

対象文字のあとに、”{n}”(波カッコ、nは数字)を指定すると、対象文字が連続してn回ある場合、マッチする。上記の場合、aa にマッチする。

a{2}b{4}

上記の複数指定した正規表現。上記の場合、”a” を 2回、”b” を 4回 なので、aabbbb にマッチする。

a{2,}

対象文字のあとに、”{n,}”を指定すると、対象文字が連続して n回以上 ある場合、マッチする。上記の場合、aa, aaa, aaaa, aaaaa, … にマッチする。

a{2,4}

対象文字のあとに、”{n, m}”を指定すると、対象文字が連続して n回以上 かつ m回以下 ある場合、マッチする。上記の場合、aa, aaa, aaaa にマッチする。

[0-9]

“[]”(角カッコ)の範囲していで、数値を指定した正規表現。”0” から “9” までの数値を指定する。上記の場合、0, 1, 2, 3, 4, 5, 6, 7, 8, 9(数値のみ)にマッチする。

[1-36-9]

上記の範囲指定を複数した正規表現。”1″ から “3” または “6” から “9” の数値にマッチする。上記の場合、1, 2, 3, 6, 7, 8, 9 にマッチする。

\d

数値の場合のみにマッチする。”[0-9]” と同様。上記の場合、0, 1, 2, 3, 4, 5, 6, 7, 8, 9(数値のみ)にマッチする。

\D

数値以外の文字、記号にマッチする。”[^0-9]” や “[^\d]”といった数値の否定と同様。

[^0-9]

“[]”(角カッコ)内の先頭に記載した “^”(キャレット)は否定の正規表現。”[0-9]”で数値を指定し、それを否定する。[^\D]も同様。上記の場合、数値以外にマッチする。

0[89]0-\d{4}-\d{4}

携帯番号(080-xxxx-xxxx, 090-xxxx-xxxx)を指定した正規表現。”080″ または “090” で始まり、”-“(ハイフン)で区切られた数値4桁がある場合、マッチする。

^abc

“^”(キャレットやチルドやハットと呼ぶ)が行の先頭を指定する。上記の場合、行の先頭にある “abc” にマッチする。

abc$

“$”(ドル)が行の末尾を指定する。上記の場合、行の末尾にある “abc” にマッチする。

^abc$

行の先頭と末尾にある “abc” つまり 行に “abc” のみの文字列にマッチする。

Python ディレクトリ配下のファイルの一覧を再帰的に取得する

ディレクトリ直下のファイル一覧、ディレクトリ一覧を3つの方法で取得します。

ディレクトリは以下、ファイルはtxtとlogの2種類です。

ディレクトリ、ファイル構成

sample_dir
  │  
  │  f_01.txt
  │  f_02.log
  │
  ├─d_01
  │      f_01_1.txt
  │      f_01_2.txt
  │      f_01_3.txt
  │
  └─d_02
          f_02_1.log


pathlibで ディレクトリ配下のファイル一覧を取得する

pathlib.Pathを利用して、 拡張子を指定したファイル一覧およびディレクトリとファイル一覧を表示する サンプルコード です。

import pathlib

p = pathlib.Path("sample_dir")

# ディレクトリ配下のテキストファイル一覧を表示(拡張子指定)
for f in p.glob("**/*.txt"):
    print(f)

print()

# ディレクトリ配下のディレクトリ、ファイル一覧を表示
for f in p.glob("**/*"):
    print(f)


# - 結果1
# sample_dir\f_01.txt
# sample_dir\d_01\f_01_1.txt
# sample_dir\d_01\f_01_2.txt
# sample_dir\d_01\f_01_3.txt

# - 結果2
# sample_dir\d_01
# sample_dir\d_02
# sample_dir\f_01.txt
# sample_dir\f_02.log
# sample_dir\d_01\f_01_1.txt
# sample_dir\d_01\f_01_2.txt
# sample_dir\d_01\f_01_3.txt
# sample_dir\d_02\f_02_1.log

pathlib.Path関数にディレクトリのパスを指定します。glob関数で取得するサンプルは相対パスですが、絶対パスも指定可能です。

pathlibの詳細については、公式ドキュメントを参照ください。


globでディレクトリ配下のファイル一覧を取得する

globを利用して、拡張子を指定したファイル一覧およびディレクトリとファイル一覧を表示する サンプルコード です。

import glob

TARGET_DIR = "sample_dir"

# ディレクトリ配下のテキストファイル一覧を表示(拡張子指定)
for f in glob.glob(TARGET_DIR + "/**/*.txt", recursive=True):
    print(f)

print()

# ディレクトリ配下のディレクトリ、ファイル一覧を表示
for f in glob.glob(TARGET_DIR + "/**", recursive=True):
    print(f)


# - 結果1
# sample_dir\f_01.txt
# sample_dir\d_01\f_01_1.txt
# sample_dir\d_01\f_01_2.txt
# sample_dir\d_01\f_01_3.txt

# - 結果2
# sample_dir\
# sample_dir\d_01
# sample_dir\d_01\f_01_1.txt
# sample_dir\d_01\f_01_2.txt
# sample_dir\d_01\f_01_3.txt
# sample_dir\d_02
# sample_dir\d_02\f_02_1.log
# sample_dir\f_01.txt
# sample_dir\f_02.log

glob.glob関数にパスを指定します、再帰的に検索する行うには、「recursive」に「True」を指定します。

globの詳細については、公式ドキュメントを参照ください。


walkでディレクトリ配下のファイル一覧を取得する

os.walkを利用して、拡張子を指定したファイル一覧およびディレクトリとファイル一覧を表示する サンプルコード です。


import os

TARGET_DIR = "sample_dir"

# ディレクトリ配下のテキストファイル一覧を表示
for dir_path, dir_names, file_names in os.walk(TARGET_DIR):
    for file_name in file_names:
        if ".txt" in file_name:
            print(os.path.join(dir_path, file_name))

print()

# ディレクトリ配下のディレクトリ、ファイル一覧を表示
for dir_path, dir_names, file_names in os.walk(TARGET_DIR):
    for dir_name in dir_names:
        print(os.path.join(dir_path, dir_name))
    for file_name in file_names:
        f = os.path.join(dir_path, file_name)
        print(f)


# - 結果1
# sample_dir\f_01.txt
# sample_dir\d_01\f_01_1.txt
# sample_dir\d_01\f_01_2.txt
# sample_dir\d_01\f_01_3.txt

# - 結果2
# sample_dir\d_01
# sample_dir\d_02
# sample_dir\f_01.txt
# sample_dir\f_02.log
# sample_dir\d_01\f_01_1.txt
# sample_dir\d_01\f_01_2.txt
# sample_dir\d_01\f_01_3.txt
# sample_dir\d_02\f_02_1.log


os.walk関数にパスを指定します。これまでと違うのは、os.walkでは、ディレクトリパス、ディレクトリ名、ファイル名の3つの戻り値が返却されます。

os.walkの詳細については、公式ドキュメントを参照ください。

Python 型を確認、チェックする

型の確認方法と型チェックをする記載例です。

Python 型を確認する

type(object)

type(1) -> <class ‘int’>


Python 型をチェックする

isinstance(object, class)

isinstance(1, int) -> True

Python 型を確認、チェックする サンプルコード


# int
i = 1
print(type(i))
print(isinstance(i, int))

# str
s = "a"
print(type(s))
print(isinstance(s, str))

# list
l = ["a", 1]
print(type(l))
print(isinstance(l, list))

# dict
d = {"key": "value"}
print(type(d))
print(isinstance(d, dict))

# tuple
t = (1, 2)
print(type(t))
print(isinstance(t, tuple))

print()

# int check.int or listなら True.
print(isinstance(i, (int, list)))
# str check.int or listなら True.
print(isinstance(s, (int, list)))
# list check.int or listなら True.
print(isinstance(l, (int, list)))
# dict check.int or listなら True.
print(isinstance(d, (int, list)))


# ===== 出力例 =====
# <class 'int'>
# True
# <class 'str'>
# True
# <class 'list'>
# True
# <class 'dict'>
# True
# <class 'tuple'>
# True

# True
# False
# True
# False


Python Printを改行なしにする

print関数のデフォルト設定では、出力文字の末尾に改行コードが設定されます。endパラメータを追加することで、変更できます。

Printを改行なしにする

print(“hoge”, end=””)

end=””(空文字)を設定します

Printの区切り文字をなしにする

print(“foo”, “bar”, sep=””)

sep=””(空文字)を設定します

サンプルコード

# デフォルトは末尾が改行コード
print("line_01")
print("line_02")
# 改行なし
print("line_03", end="")
print("line_04")
# カンマ
print("line_05", end=",")
print("line_06")

print()

# 文字列複数
print("foo", "bar")
# 区切り文字をなし
print("foo", "bar", sep="")

# ===== 出力例 =====
# line_01
# line_02
# line_03line_04
# line_05,line_06

# foo bar
# foobar

PostgreSQL psqlでログインするコマンド パスワード省略(パスワードあり/なし)

よく使うのでメモ。

コマンドラインからpsqlに接続する(パスワードあり)

パターン1

psql “postgresql://{ユーザー名}:{パスワード}@{ホスト名}:{ポート番号}/{データベース名}”

パターン2

psql “user={ユーザー名} password={パスワード} host={ホスト名} port={ポート番号} dbname={データベース名}”


コマンドラインからpsqlに接続する(パスワードなし)

パターン1

psql “postgresql://{ユーザー名}@{ホスト名}:{ポート番号}/{データベース名}”

パターン2

psql “user={ユーザー名} host={ホスト名} port={ポート番号} dbname={データベース名}”

パターン3

psql -U {ユーザー名} -h {ホスト名} -p {ポート番号} -d {データベース名}


psqlからログアウトする

\q

Bash(Shell)でディレクトリ、リストをforループする

よく使うのでメモとして掲載します。

Bash(Shell)でディレクトリ、リストをforループする サンプルコード


#!/bin/bash

echo "ディレクトリ直下のファイルをループ"
dir_path="sample_dir/*"
for dir in $dir_path; do
    echo "$dir"
done

echo --------------------------

# リスト定義
declare -a list=(
    "foo"
    "bar"
    "baz"
)

echo "リストをループする"
for row in "${list[@]}"; do
    echo "$row"
done

echo "インデックス付きでリストをループする"
for i in "${!list[@]}"; do
    echo "$i : ${list[$i]}"
done

echo --------------------------

echo "連番でループ{}"
for i in {0..3}; do
    echo ${i}
done

echo "連番でループ seq"
for i in $(seq 0 3); do
    echo "$i"
done

実行結果


# ディレクトリ直下のファイルをループ
sample_dir/sample_01.txt
sample_dir/sample_02.txt
--------------------------
# リストをループする
foo
bar
baz
# インデックス付きでリストをループする
0 : foo
1 : bar
2 : baz
--------------------------
# 連番でループ{ }
0
1
2
3
# 連番でループ seq
0
1
2
3


ディレクトリ直下のファイルをfor文でループ


#!/bin/bash

# ディレクトリ直下のファイルをループ
dir_path="sample_dir/*"
echo "\$dir_path -> " $dir_path
for dir in $dir_path; do
    echo "$dir"
done

# 結果
# 
# $dir_path ->  sample_dir/sample_01.txt sample_dir/sample_02.txt
# sample_dir/sample_01.txt
# sample_dir/sample_02.txt


リストをfor文でループ、インデックス付きfor文でループ

#!/bin/bash

# リスト定義
declare -a list=(
    "foo"
    "bar"
    "baz"
)

# リストをループする
echo "\$\"{list[@]}\" -> " "${list[@]}"
for row in "${list[@]}"; do
    echo "$row"
done

echo

# インデックス付きでリストをループする
echo "\$\"{!list[@]}\" -> " "${!list[@]}"
for i in "${!list[@]}"; do
    echo "$i : ${list[$i]}"
done

# 結果
# 
# $"{list[@]}" ->  foo bar baz
# foo
# bar
# baz

# $"{!list[@]}" ->  0 1 2
# 0 : foo
# 1 : bar
# 2 : baz


連番をfor文でループ


#!/bin/bash

# 連番でループ {}
echo "{0..3} -> " {0..3}
for i in {0..3}; do
    echo ${i}
done

echo

# 連番でループ seq
echo "\$(seq 0 3) -> " $(seq 0 3)
for i in $(seq 0 3); do
    echo "$i"
done

# 結果
#
# {0..3} ->  0 1 2 3
# 0
# 1
# 2
# 3

# $(seq 0 3) ->  0 1 2 3
# 0
# 1
# 2
# 3

IBM WatsonのVisual Recognitionの独自クラスで画像認識する (Python)

前回、shellとCurlで利用してみましたが、今回はPythonで独自クラスを利用してみます。

shellとCurlのサンプルコード掲載投稿はこちら

Visual Recognitionで画像認識する

shellとCurlでやったおさらいとなります。アカウントを作成し、APIキーを取得したら、classifyメソッドを利用して画像認識を行います。

画像識別するフルーツの画像

https://watson-developer-cloud.github.io/doc-tutorial-downloads/visual-recognition/fruitbowl.jpg


PythonでWatsonを利用するには、pipで”ibm-watson”モジュールをインストールします。

ibm-watsonモジュールをpipでインストール

# ibm-watsonをインストールする
pip install --upgrade "ibm-watson>=4.1.0"

Python 画像認識 classify サンプルコード

import json
from ibm_watson import VisualRecognitionV3
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

authenticator = IAMAuthenticator("{api keyを設定する}")
visual_recognition = VisualRecognitionV3(
    version="2018-03-19", authenticator=authenticator
)

visual_recognition.set_service_url(
    "https://api.us-south.visual-recognition.watson.cloud.ibm.com"
)

with open("fruitbowl.jpg", "rb") as images_file:
    classes = visual_recognition.classify(
        images_file=images_file,
        accept_language="ja",
        threshold="0.6"
    ).get_result()
    print(json.dumps(classes, ensure_ascii=False, indent=2))

APIKEYとバージョンを指定して、VisualRecognitionインスタンスを生成します。

set_service_urlでエンドポイントのURLを指定します。

VisualRecognitionのclassifyのパラメータに以下を指定します。

  • images_file・・・画像ファイル
  • accept_language・・・言語
  • threshold・・・しきい値(返却される分類のスコアの最低値)


classifyの実行結果

$ python classify.py 
{
  "images": [
    {
      "classifiers": [
        {
          "classifier_id": "default",
          "name": "default",
          "classes": [
            {
              "class": "果実",
              "score": 0.788
            },
            {
              "class": "オリーブ色",
              "score": 0.973
            },
            {
              "class": "レモン・イエロー (色)",
              "score": 0.789
            }
          ]
        }
      ],
      "image": "fruitbowl.jpg"
    }
  ],
  "images_processed": 1,
  "custom_classes": 0
}

結果が取得できました。レスポンスの各値については、公式ドキュメントをご参照ください。

公式ドキュメントURL

https://cloud.ibm.com/apidocs/visual-recognition/visual-recognition-v3?code=python#classify-images


Visual Recognitionで画像認識用の独自クラスを作成する

サンプルで記載されている犬の画像セット3つと猫の画像セット1つを利用して独自クラスを作成します。犬の画像はポジティブ、猫の画像はネガティブな学習データとして利用します。

画像URLは公式ドキュメントのページから取得できます。公式ドキュメントのURLはこちら

Python 独自クラス作成 create_classifier サンプルコード

import json
from ibm_watson import VisualRecognitionV3
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator


def exec():
    authenticator = IAMAuthenticator("{API KEYを設定する}")
    visual_recognition = VisualRecognitionV3(
        version="2018-03-19", authenticator=authenticator
    )

    visual_recognition.set_service_url(
        "https://api.us-south.visual-recognition.watson.cloud.ibm.com"
    )

    with open("beagle.zip", "rb") as beagle, open(
        "golden-retriever.zip", "rb"
    ) as goldenretriever, open("husky.zip", "rb") as husky, open(
        "cats.zip", "rb"
    ) as cats:
        model = visual_recognition.create_classifier(
            "dogs",
            positive_examples={
                "beagle": beagle,
                "goldenretriever": goldenretriever,
                "husky": husky,
            },
            negative_examples=cats,
        ).get_result()
    print(json.dumps(model, indent=2))


if __name__ == "__main__":
    exec()

API KEYを設定してVisualRecognitionインスタンスを生成し、サービスのURLを設定するところまでは、classifyメソッドと同じです。

学習用画像データが入ったzipファイルをwith openで展開します。カンマ区切りで繋げることで、4つのzipファイルを引数に渡します。

独自クラスを作るには、create_classifierメソッド作成します。第一引数には、nameを指定します。positive_examplesでは、犬のクラスを構成する画像ファイルをclassnameキーと一緒に指定します (”beagle”: beagle、”goldenretriever”: goldenretriever、”husky”: husky) 。negative_examplesには、猫の画像ファイルを指定してます。ネガティブ例にはクラス名の指定は不要です。

なお、 .jpgまたは.pngの画像ファイルが 1つのzipに最低でも10個必要で、最大数は10,000画像 または 100MBのようです。

create_classifierの実行結果

$ python create_classifier.py
{
  "classifier_id": "dogs_113492332",
  "name": "dogs",
  "status": "training",
  "owner": "7b33a505-95fc-4f71-a419-17a78f96f78c",
  "created": "2019-12-28T21:19:02.872Z",
  "updated": "2019-12-28T21:19:02.872Z",
  "classes": [
    {
      "class": "husky"
    },
    {
      "class": "goldenretriever"
    },
    {
      "class": "beagle"
    }
  ],
  "core_ml_enabled": true
}

結果が取得できました。レスポンスの各値については、公式ドキュメントをご参照ください。

公式ドキュメントURL

https://cloud.ibm.com/apidocs/visual-recognition/visual-recognition-v3#create-a-classifier

独自クラスを利用するには最初のclassifyメソッドのパラメータに”owners=[“me”]”を追加します。

犬(ハスキー)の画像を独自クラスとデフォルトクラスとで、それぞれ画像認識してみます。

独自クラス classify 実行結果

{
  "images": [
    {
      "classifiers": [
        {
          "classifier_id": "dogs_113492332",
          "name": "dogs",
          "classes": [
            {
              "class": "husky",
              "score": 0.843
            }
          ]
        }
      ],
      "image": "husky2.jpg"
    }
  ],
  "images_processed": 1,
  "custom_classes": 3
}

huskyクラスで、0.843という結果が返却されました。また、独自クラスの言語は日本語指定できないようです。

デフォルトクラス classify 実行結果

{
  "images": [
    {
      "classifiers": [
        {
          "classifier_id": "default",
          "name": "default",
          "classes": [
            {
              "class": "犬",
              "score": 0.98,
              "type_hierarchy": "/動物/哺乳類/肉食動物/イヌ/犬"
            },
            {
              "class": "イヌ",
              "score": 0.887
            },
            {
              "class": "肉食動物",
              "score": 0.887
            },
            {
              "class": "哺乳類",
              "score": 0.887
            },
            {
              "class": "動物",
              "score": 0.982
            },
            {
              "class": "シベリアン・ハスキー",
              "score": 0.739,
              "type_hierarchy": "/動物/飼い慣らされた動物/犬/シベリアン・ハスキー"
            },
            {
              "class": "飼い慣らされた動物",
              "score": 0.883
            },
            {
              "class": "灰白色",
              "score": 0.807
            },
            {
              "class": "緑がかった色",
              "score": 0.79
            }
          ]
        }
      ],
      "image": "husky2.jpg"
    }
  ],
  "images_processed": 1,
  "custom_classes": 0
}

犬で0.98、何故かカタカナのイヌでも0.887、シベリアン・ハスキーが0.739、また色も識別できています。

ハスキーかどうかのスコア0.843>0.739と、独自クラスのほうが優秀だといえるのでしょうか。

しかし、犬が0.98など色々返却されるデフォルトのほうがなんとなく優秀そうな。。。学習量を増やした場合、精度どのくらいあがるかなど、もう少し検証したいと思います。

PostgreSQL psqlで引数とSQLファイルを指定して実行する

psqlとはPostgreSQLのターミナル型SQLクライアントです。

引数に指定した値をSQLファイルの変数にバインドします。

psqlで引数とSQLファイルを指定して実行する サンプルコード

sample.sql

実行するSQLファイル、”:変数”の箇所を置き換えます。

select :foo,
       :bar,
       :hoge;

p_exec_file.sh

実行するshellです。psqlを呼び出し、”-f”オプションでSQLファイルを指定し、”-v”オプションで引数名と値を設定します。”–echo-all”は実行したSQLを結果と一緒に出力します。

#!/bin/bash

DB_USER="{user_name}"
DB_PWD="{password}"
DB_SERVER="{db_server_url}"
DB_PORT="{db_port}"
DB_NAME="{db_name}"

psql \
    -d "postgresql://$DB_USER:$DB_PWD@$DB_SERVER:$DB_PORT/$DB_NAME" \
    -f "sample.sql" \
    -v foo="now()" \
    -v bar="1" \
    -v hoge="'test_str'" \
    --echo-all


実行結果

p_exec_file.shを実行します。実行したSQL文と結果が出力されます。”foo”に”now()”、”bar”に”1″(数値)、”hoge”に”test_str”(文字)が設定されています。

$ ./p_exec_file.sh
select :foo,
       :bar,
       :hoge;
              now              | ?column? | ?column?
-------------------------------+----------+----------
 2019-12-28 16:10:25.343578+09 |        1 | test_str
(1 行)

Crl2CapでWindowsのCtrlとCapsLockを入れ替える

自分が新しくWindowsをインストールしたら最初にやることの一つです。

CtrlキーとCapsLockキーを入れ替えます。MicroSoft純正で安心感もあります。

公式URLはこちら


管理者権限でコマンドプロンプトを起動して、以下のコマンドを実行します。

ctrl2cap /install

実行完了したらWindowsを再起動すれば完了です。