コピペコードで快適生活

明日使えるソースを自分のために

第38回҈҈҉҈҈҉シ҈҉ェ҈҉ル҈҉芸҈҉勉҈҉強҈҉会メモ

https://b.ueda.tech/?post=shellgei_38 より学んだことメモ

xxd コマンド

対象を16進数でダンプする/16進数から復元する。
pオプションはpostscript形式でダンプするの意味。

# ダンプする
echo "ほげほげ" | xxd -p

# 復元する 
echo "ほげほげ" | xxd -p | xxd -r -p

# もやもやの文字コード
echo d288 | xxd -r -p
echo d289 | xxd -r -p

grep -o オプション

マッチした行ではなくマッチした箇所のみを返す

# なのでこうすれば縦に並ぶ
echo "あいうえお" | grep -o .

grep -f オプション

検索条件を保存したファイルでフィルターする

cat cond.txt
あ
い

echo "あいうえお" | grep -o . | grep -f cond.txt
あ
い

# リダイレクションと組み合わせる
cat cond.txt
あいうえお

echo "あいうえお" | grep -o . | grep -f <(grep -o . cond.txt)
あ
い

sort -kオプション

# 2項目目以降でソート
cat sample.txt | sort -k 2

# 2項目目だけでソート
cat sample.txt | sort -k 2,2

# 1項目目だけを数値としてソート
cat sample.txt | sort -k 1,1n

uniqで重複を抽出する

重複行の抽出する

# dオプションで重複のみ抽出
# fオプションで重複チェック除外フィールドを指定 (1を指定した場合は2以降で重複チェック)
cat sample.txt | sort -k 2,2 | uniq -d -f 1

trコマンド

# 置き換え(文字数は揃える必要がある)
echo 012 | gtr 012 abc

# 大文字小文字変換
echo ABC | gtr A-Z a-z

# 改行コードに変換
echo "A B C" | gtr ' ' \\n

# 指定文字以外を削除する
echo "1234567890abcdef" | gtr -dc 1234567890

nlコマンド

行数を表示

echo "A B C" | tr ' ' \\n | nl

foldコマンド

指定した幅で改行する

echo "ABCDEFGHIJK" | gfold -b5

ガウス分布な乱数生成

※0-1間の一様乱数を12回足して6引いた値の集合は、標準偏差1のガウス分布に従う。
http://www.geocities.jp/jun930/etc/varianceofrandom.html
https://bellcurve.jp/statistics/blog/17953.html

cat /dev/urandom | gtr -dc 0-9 | gfold -b10 | gsed 's/^/0./' |
gawk '{a+=$1}NR%12==0{print (a-6);a=0}'

指定範囲の文字を全部出力

echo {A..Z}
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

カンマのところで改行を入れる

cat sample.txt | gsed -e "s/,/,\\n/g"

nkf(NetworkKanjiFilter)

文字コード/改行コードの変換を行うコマンド

# -w UTF8に変換
# -Lu LFに変換
# -x 半角カタカナを半角のまま
cat myoho_shinji.txt | nkf -wLux

xargsで、引数の数を指定する

cat hogefuga.txt
hoge
fuga

cat hogefuga.txt | xargs -n 2
hoge fuga

awkの中で、コマンドの実行結果を得る

# コマンド | getline 変数 で、
# 変数にコマンドの実行結果が入る
cat data.txt | gawk '{"hostname" | getline x; print x;}'
suzukake.local
suzukake.local
suzukake.local
suzukake.local

awkでバッファを出力する

fflush();

factorコマンドで素因数分解する

gfactor 12
12: 2 2 3

Q7分解

a^2 + b^2がab + 1で割り切れる正の整数の組合せa,bを生成してください(ランダムで良いです)。また、このとき、(a^2+b^2)/(ab+1)が正の整数の二乗になっていることを確かめてください。

awkを分解して見てみれば怖くない。

cat /dev/urandom | gtr -dc 0-9 | gfold -b2 | gsed 's/^0*//' | xargs -n 2 |
gawk '
($1*$1 + $2*$2) % ($1*$2+1) == 0 { # この条件に該当した場合に{}内を実行する
  a = ($1*$1 + $2*$2)/($1*$2+1); # 変数代入
  "gfactor " a | getline x ; # factorコマンドで素因数分解した結果を変数xに格納する
  print $1,$2,x; # 出力
  fflush() # バッファ出力
}
' | # 4 64 16: 2 2 2 2 のように右辺に素因数分解した結果が出力される
gawk '{
  for(i=4;i<=NF;i++) a[$i]++; # $iでi番目の値が取れる。上記の例でいうと、a[2]に4が入る。
  printf $1" "$2" "$3;
  x="OK";
  for(k in a){
    if(a[k]%2 == 1) x="NG"; # 同じ値が2で割り切れない数繰り返された = 二乗にならない場合
  }
  print x;
}'

Q8分解

数列x_{i+1} = a * x_i * (1 - x_i)について、xの初期値を0.5としてAWKで出力して、百万回以上連続で、これまで出てきていない数字を出力してください。ただし、aは3以上、4未満の小数から選んでください。これに飽き足らない人は限界に挑戦してください。

これも何やっているか分解して考えれば怖くない。

cat /dev/urandom | gtr -dc 0-9 | gfold -b10 | gsed 's/^/0./' | # 0.xの数値をランダムに出す
gawk '{print $1*4}' | gawk '$1>=3' | # 3以上4未満に揃える
while read a ; # 入力がある限り繰り返す
do
  gawk -v a=$a ' # シェル変数をawkの変数に代入
  BEGIN{
    OFMT="%.20f"; # 小数表示20桁とする(デフォだと指数表示になるため)
    x=0.5; # 数列の初期値を設定
    while(1){
      print x; # 数列の値を出力
      x=a*x*(1-x) # 数列の次の値を計算
    }
  }
  ' |
  head -n 1000000 | # 百万行出力
  sort -u | # 重複を削除して並び替え
  wc -l | # それが何行あるか
  gawk -v a=$a '
    $1==1000000 { # 百万行あれば
      print a,$1  # 出力する
    }
  ';
done |
head -n 1

npmでパッケージ公開するまでのコマンド

# npm設定確認
# レジストリのURLも確認できる
npm config list

# レジストリを変える
npm set registry http://npm.example.com

# レジストリ戻す
npm set registry https://registry.npmjs.org/ 

# レジストリにユーザを追加
npm adduser --registry http://npm.example.com

# ログインする
# ~/.npmrc にログイン情報が保持されるので1回だけ叩けばOK
npm login

# パッケージのpublish
npm publish

# まちがえてpublishしたのを削除する
npm unpublish <package-name>@<version>

npm レジストリサイト
https://www.npmjs.com/

class_evalを使って、classに自由な名前でメソッドを追加

concernに書くとこんな感じか。

#
# include ::Logica::DateRangeSearchable
# date_range_name_is :validity, :valid
#
# klass.valid
#   -> validity_start_at, validity_end_atが期間内のみ取り出す
# instance.valid?
#   -> validity_start_at, validity_end_atが期間内か
#
module Logica
  module DateRangeSearchable
    extend ActiveSupport::Concern

    class_methods do
      def date_range_name_is(name, method_name = nil)
        method_name = name if method_name.blank?

        validation_name = "#{name}_start_lt_end_validation".to_sym
        validate validation_name

        class_eval <<-EOS
          def #{method_name}?(now = Time.zone.now)
            (self.#{name}_start_at.nil? || self.#{name}_start_at <= now) &&
            (self.#{name}_end_at.nil? || self.#{name}_end_at >= now )
          end

          def #{validation_name}
            if self.#{name}_start_at.nil? || self.#{name}_end_at.nil?
              return true
            end
            if self.#{name}_end_at <= self.#{name}_start_at
              message = I18n.t('errors.messages.less_than', count: self.#{name}_end_at)
              self.errors.add("#{name}_start_at".to_sym, message)
            end
          end

          def self.#{method_name}_conds(now = Time.zone.now)
            a = arel_table[:#{name}_start_at].lteq(now).or(arel_table[:#{name}_start_at].eq(nil))
            b = arel_table[:#{name}_end_at].gteq(now).or(arel_table[:#{name}_end_at].eq(nil))
            a.and(b)
          end
        EOS

        class_eval do
          scope method_name.to_sym, -> (now = Time.zone.now) {
            where(self.try("#{method_name}_conds", now))
          }
        end

      end
    end
  end
end

macOSのcurlで海外アクセスのチェックをやるときのproxy設定メモ

macOScurlで海外アクセスのチェックをやるときのproxy設定メモ

HTTPのproxy

フリーのproxy情報はこの辺から
http://www.freeproxylists.net/ja/

# 設定
PROXY_HOST=xxx.xxx.xxx.xxx
PROXY_PORT=xxxx
export http_proxy="http://${PROXY_HOST}:${PROXY_PORT}"

# 確認
curl http://ipconfig.io

# 解除
export http_proxy=""

HTTPSのproxy

フリーのproxy情報はこの辺から
https://www.sslproxies.org/

# 設定
SSL_PROXY_HOST=xxx.xxx.xxx.xxx
SSL_PROXY_PORT=xxxx
export https_proxy="https://${SSL_PROXY_HOST}:${SSL_PROXY_PORT}"

# 確認
curl https://ipconfig.io

# 解除
export https_proxy=""

PostgreSQLでシーケンスの位置を変える

--「テーブル名_カラム名_seq」が名称となる。

-- 確認
SELECT * FROM app_users_id_seq;
 sequence_name | last_value | start_value | increment_by |      max_value      | min_value | cache_value | log_cnt | is_cycled | is_called
---------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
 users_id_seq  |      15711 |           1 |            1 | 9223372036854775807 |         1 |           1 |      30 | f         | t

-- インクリメント
SELECT nextval('app_users_id_seq');

-- 値を直接変える
SELECT setval('app_users_id_seq', 20001);

Rubyでたまにしか使わないけど便利なメソッドメモ

備忘のため。随時追加していく。

Ruby

# フィールドをもつモックオブジェクトを作る
Struct.new(:name, :tel).new('hogeo', '090xxxxxxxx')
# => #<struct name="hogeo", tel="090xxxxxxxx">

# irbでeach回して処理した後、そのリストを出力させたくない
list.each do |row|
  # 何かしらの処理
end; 0 # ここで ; 0 入れる。

# getter/setterがないインスタンス変数にアクセス
obj.instance_variable_defined?('@hoge')
obj.instance_variable_get('@hoge')
obj.instance_variable_set('@hoge', 'hogehoge')

# 余計な改行コードを chomp で消す
fr = File.open('ids.txt', 'r')
line = fr.gets
# => "0000a432-67cb-4b07-8bba-58780616f6c7\n"
line = fr.gets.chomp
# => "0000a5bd-cf86-4eda-be5e-0b81dafa5cd0"
fr.close

Rails

# 引数の文字列で指定した名前で定数を探す
'::MyApp::User'.constantize
# => MyApp::User(id: integer, first_name: string, last_name: 

# ハッシュにシンボルでも文字列でもアクセスできるように
hash = { hoge: 'fuga' }.with_indifferent_access
hash[:hoge]  #=> "fuga"
hash['hoge'] #=> "fuga"

# モデルやフィールドの日本語名を取得
def t_ar(model, attr = false)
  if attr
    return model.human_attribute_name(attr)
  else
    return model.model_name.human
  end
end

# ハッシュの一部をフィルターする
filter = ActionDispatch::Http::ParameterFilter.new(['email', 'password'])
filterd_params = filter.filter(params)

# 生SELECT文を書く
con = ActiveRecord::Base.connection
result = con.select_all('SELECT name FROM users')
result.to_a

ワンライナー

# yaml文法チェック
cat foo.yml | ruby -r yaml -e 'YAML.load STDIN'
# クエリ文字列をURLエンコード
require 'cgi'
query.split('&').map{|kv| kv.split("=").map{|_kv| CGI.escape(_kv) }.join("=") }.join('&')