Skip to main content

defold メモ

ooq.kamui

defold で気づいたことを書いていきます


gui_script から go.get_id() すると

You can only access go.* functions and values from a script instance (.script file)  

のエラーとなる
が, もともと取得済で global 下などに保存していた go_id に post することはできる


下記のエラーのさい, リビルドしてもエラー解消しなかったが, defold 再起動でエラー解消した

WARNING:RESOURCE: Resource not found: /assets/xx/xx.luac
WARNING:RESOURCE: Unable to create resource: /assets/xx/xx.scriptc
WARNING:RESOURCE: Unable to create resource: /assets/xx/xx.goc
ERROR:GAMEOBJECT: Could not instantiate game object from prototype /assets/xx/xx.goc.
WARNING:RESOURCE: Unable to create resource: /main/main.collectionc

go.get_world_position() で取得する world_position は go.set_position() のあと即時反映されない

非同期で反映される

go.get_position() で取れる position は即時反映されている


parent の付け替えと同時に, z 位置を 新 parent との相対位置で指定して変更したいとき

注意) 下記の考察を書いているとき, go.set_parent() 関数はまだないころでした
go.set_parent() ができてから, この関数でも試してみましたが, 内部的には msg.post() で parent 設定していると思われます
なので, 下記の記述はまだ有効と思います

x, y 位置は そのままか, せめて 意図しない位置に突然表示されないようにしたい

提供されている関数などの確認

parent の付け替え は

msg.post(url, "set_parent", {parent_id = p_id, keep_world_transform = 1})

で行う

msg.post() なのでこの処理は非同期

parent 付け替え後に実行する callback function を与える仕組みはなさそう

パラメータ keep_world_transform = 1 or 0 で world_position を維持するか parent との相対 position を維持するかを選択できる

ただしこれは x, y, z まとめてとなる
z だけ別に設定はできない

world position から指定する go.set_world_position() のような関数は 提供されていない

go.set_position() は即時反映されるが, その直後にその go.get_world_position() は即時反映されていないので取得できない

以上を踏まえ,

parent 付け替えと同時の z 指定 を一箇所で処理したい場合は,

z に新しい相対位置を設定

現位置 の 新 parent からの 相対 x, y を 算出して設定

keep_world_transform = 0 で parent 付け替え

が妥当 (と思われる)

これでも 1 フレームだけ変な位置に見えているかもしれないので, それもいやであれば, 位置変更も msg.post() 経由で行うようにし, disable, 位置変更, enable と順番に msg.post() する

と, ここまで考えて, msg.post() で位置変更する仕組みまで作るのであれば, keep_world_transform = 1 で parent 付け替えしたあと msg.post() 経由で z 位置変更するのが 2手でスマート


go.property("key", val) で val に function は設定できない

よって go instance に 動的に function を外部から与えられない

msg.post() のパラメータを介して function を与えようとしてもエラーとなる

やりたい場合の
案1: 与えたい function を global で管理し, idx をふっておく その idx を go.property(key, idx) にセットしておき, go.set(id, key, idx) で与える

また, 他の property 値をもとにそのとき計算して得られる値を外部から取ることもできない
( go instance ( self ) に getXxxx() といった関数 ( method ) をつけても 外部からは値を取ることができない )

あらかじめ計算した値を property に設定しておき, 外部からはその値を単純に取得する

毎フレーム変わる値の場合は, 毎フレーム計算し, 設定しておく必要がある

配列の要素数を取得したい場合もこの方法が妥当 (次に記載の方法ではできない)

または 計算に必要な値をすべて go.property(key, val) しておいて, 外部の static method ( global function ) から go.get(id, key) で取得し, 計算する


go.property("key", val) で val に array は設定できない

よって go ( self ) 配下の array に 外部から 追加, 削除などしたい 場合は on_message() を介して非同期で行う

array の要素を 外部から get することはできない


z 位置は -1 ~ 1 のあいだ


update() の中で go.delete() を呼んで自分自身を delete しても, update() 内のそのあとの処理は継続される

よって, 以降を実行しない処理イメージのときは, 明示的に return する


factory.create() で与えたパラメータは 作成される go instance の init() 内でも取れる


factory.create() のパラメータに parent はない よって, create() 時に position と parent を指定して 親との相対 position で位置設定することはできない

そうしたことがしたい場合には, parent の script から factory.create() し, そのとき与える position を 自身 ( parent ) の world_position + 相対 position にするのが無難

もしくは, collection ではじめから 親子関係を持つ go 群 を作成しておき, その collection を collectionfactory.create() する


collision は片側からだけ取りたい場合でも collision の mask 設定が相互に付いていなければ取れない


sys.save(file, data) で保存する data table の key は number か string のみ

key に hash は入れられず, err となるので注意

hash を table の val に入れて save すると, err とはならないが, いったん アプリケーションを閉じてから, また開いて同データを load すると

[12722210162474435462 (unknown)]

といったようになってしまう

なぜこうなるのか, そもそも hash() とはどういったもので, 何の利点のために導入されているのかが まだ自分には不明だが, とりあえずこれを回避する

プログラム中では hash を key にしていることが多いが, save data ではこれを string に変換する

hash -> string の逆変換 mapping は持ちたくなかったが, save を作るにあたり持たざるをえないと思われる

vmath.vector3() を save, load することはできる


go の sprite の 色味, 透明度 をパラメータで変えることはできない

( render , shader の知識があればできるのかもしれないがまだそこの知識はない )

gui node ならパラメータから 色味, 透明度 を変えられる


tilemap の tile の 一つ一つに別のフィルターをかけて color を変えることは material や dender.script の編集などをしてもできなさそう

(自分がマニュアルを読んだ限りではできなそうであった)


tilemap の component に動的に position を set して動かすことはできない
背景の 2重スクロールをやるには それぞれの go を作成して 動かす必要がありそう


go.property() に nil を設定することはできない

go.property("key", nil)

とすると, 実行時に

Invalid type (nil) supplied to go.property, must be either a number, boolean, hash, URL, vector3, vector4 or quaternion.

の err となる

各型の 0, 空 に相当する値を代入しておくのが無難

go.property("key", hash(""))
go.property("key", 0)
go.property("key", false)

などとしておく

また, 定義時は上記のように 0, 空 相当の値を入れておいても, 処理中に nil が入ってしまったときに, go.get("key") で取得しようとすると次の err となるので注意

'target_url' does not have any property called 'key'

この err msg からだと nil が入ってしまっていることを類推しにくいので 頭の片隅においておくこと


go.property() に _ から始まる変数名を使用できる

go.property("_key", hash(""))

のような property を作っても問題ない


xxx.script の go.property() 部分を dofile() で共通化することはできない (と思われる)

xxx.script の go.property() 部分を共通化したかったので, 共通部分を 別ファイルで作成し, dofile() で実行するようにしたが, できなかった

require() でやろうとしても require() は 1度しか呼ばれないため lua の仕様としてできない

とりあえず, 共通化はあきらめて, 逐次 定義することにする


gui_script から go.script の go.property() で定義されているプロパティ変数を 取得することはできない

よって, gui_script で go.property() 変数を使いたい場合は, gui に msg.post() するさいのパラメータで渡す


gui.animate() のさい, 異なる property であれば, 同一 node に複数の animation を設定することは可

うまく操作しない場合は何らかの別の原因がある


別の gui を重ねて表示するとき, それぞれの node の描画順を明示的に制御することはできない

同時に表示する gui は あらかじめ洗い出しておいて, 1つの gui として作成するのが無難

1つの gui の中であれば node の表示順を指定できる


gui の text node は node 作成 tree の順と関係なく, 文字が手前に表示される


go 内の label の文字も, 他の go の z position や sprite の z position と 関係なく, 手前に表示される


node が gui.set_enabled(node, false) で gui.clone() されたとき, できた node も gui.is_enabled() == false となる


gui.delete_node() は配下の node も自動的に削除される 複製は gui.clone() と gui.clone_tree() とわかれているが, 削除は gui.delete_node() のみ


はじめから親子関係をもつ go 定義 file をつくることはできない
collection でならはじめから親子関係をもつ go 群 を作成可能


go.property() に vmath.vector3() を定義できる

lua メモ

ooq.kamui

lua の初学者が覚えたことをメモしていきます

for 文の idx, val は for 内での local 変数になる

$ cat tst001.lua 
function test()

local ar = {1,2,3,4,5}

local idx = 200
local val

for idx, val in pairs(ar) do
print(idx)
end
print(idx, val)
end

test()
print(idx)

$ lua tst001.lua
1
2
3
4
5
200 nil
nil

: および . の前後は 改行 空白 を挟んでも可

これによって method call の戻り値の object から さらに method call を改行ありでできる

$ cat test.lua 
Cls = {
new = function ()
local obj = {}
for key, fnc in pairs(Cls) do
if key ~= "new" then
obj[key] = fnc
end
end
return obj
end,

method1 = function (slf)
print("method1")
return slf
end,

method2 = function (slf)
print("method2")
return slf
end,
}

Cls.new()
:method1()
:method2()

$ lua test.lua
method1
method2

可変長引数の個数

$ cat tst001.lua
function a001(...)
local prm = {...}
print (#prm)
end

a001("aaa", "bbb", "ccc")
a001("aaa", "bbb", "ccc", "ddd")
a001("aaa", "bbb", "ccc", nil, "eee") -- 間に nil があってもよさそう
a001("aaa", nil, "ccc", nil, "eee", "fff")
a001("aaa", nil, "ccc", nil, "eee", "fff", nil) -- 最後が nil だとカウントされない
$ lua tst002.lua
3
4
5
6
6

うまくすれば method overload ぽいこともできそうだけど, いまどきはあんまり method overload やらないのかな .. ???

ボクは 段階的リファクタリングの過程で method overload 使ったりします

return 変数列挙 の function を return 文で call して, 変数列挙ごと受継ぐことは可

$ cat tst.lua
function a()
local x, y = 1, 2
return x, y
end

function b()
return a()
end

local c1, c2 = b()
print(c1, c2)

$ lua tst.lua
1 2

「local 変数 の 列挙定義」 かつ 「関数戻り値 で 代入」 は 可

$ cat test001.lua 
function fnc1()

local val1, val2 = fnc2()

print(val1, val2)

return val1, val2
end

function fnc2()
return 88, 99
end

local a, b = fnc1()
print(a, b)

$ lua test001.lua
88 99
88 99

table コンストラクタ内で直接 function を定義することも可

$ cat test.lua 
fnc_ar = {
function ()
print("fnc1")
end,
function ()
print("fnc2")
end,
}

fnc_ar[1]()
fnc_ar[2]()

$ lua test.lua
fnc1
fnc2

文字列の分割

> s = "hello world from Lua"
> for w in s:gmatch("%a+") do
>> print(w)
>> end
hello
world
from
Lua

配列 を for ループ中に その配列の要素を table.remove() するときの注意

idx increment と in pairs() の違い

> a = {"a", "b", "c"}
> for i = 1, #a do
>> print(i, a[i])
>> table.remove(a)
>> end
1 a
2 b
3 nil
-- 最初の要素数分ループする
-- つまり #a を初回評価するのみ (と思われる)
> a = {"a", "b", "c"} 
> for i, val in pairs(a) do
>> print(i, val)
>> table.remove(a)
>> end
1 a
2 b
-- 最初の要素数分ループしない

ケースによっては nil 代入による削除で行ってもよい
連想配列の要素の削除 の項 も参照
nil 代入による削除 は idx 配列でも可能

ちなみに while では #a が都度評価される

a = {1,2,3}
> while #a > 0 do
>> print(#a)
>> table.remove(a)
>> end
3
2
1

三項演算

x = (condition) and val1 or val2

変数, 引数 の default 値 設定

val = val or default_val

値が nil の配列は pairs() でとばされる

> ar = {1,nil,3}
> for idx,val in pairs(ar) do print(idx,val) end
1 1
3 3

連想配列の要素の削除

連想配列の値に nil を代入することは その変数(要素)を削除することと同等なのでこれを利用する

> a = {a = "a", b = "b", c = "c"}
> for key, val in pairs(a) do print(key, val) end
a a
b b
c c

> a.b = nil
> for key, val in pairs(a) do print(key, val) end
a a
c c

> -- そもそも 存在しない key を参照しようとしても
> -- nil が返るのみでエラーとはならない
> print(a.d)
nil

> -- なので, 値に nil を入れると,
> -- それまでに宣言されていない変数と挙動が同等となる

> -- また key 名を明示的に指定しない参照は
> -- pairs() ぐらいしかない (と思われる, 素直な作りであれば)
> -- pairs() は値が nil の場合には処理をとばすので,
> -- その key がないのと挙動が同等となる


> -- 注) idx 配列の要素数や unpack() では nil 値でもとばされません
> b = {"a", nil, "c"}
> print(#b)
3
> table.unpack(b)
a nil c

配列を空にする ( 参照している配列は変えずに中身の要素を空にする )

pairs() で回してすべての値に nil を入れる

連想配列と idx 配列が混在しても可

> a = {1, 2, a = "a", b = "b", 3, d = "d"}
> for key, val in pairs(a) do print(key, val) end
1 1
2 2
3 3
d d
a a
b b
> for key, val in pairs(a) do a[key] = nil end
>
> for key, val in pairs(a) do print(key, val) end
>
> for idx = 1, #a do print(a[idx]) end
>

table を二重参照している場合, 一方の変数から テーブルコンストラクタ ( val = ) で初期化すると もう一方の変数に反映されないので, これを活用する

> a = {1, 2, 3}
> b = a
> a = {}
> print(table.unpack(b))
1 2 3

> a = {1, 2, 3}
> b = a
> for idx, val in pairs(a) do a[idx] = nil end
> print(table.unpack(b))
-- <- 空配列

idx 配列の途中に nil を入れても idx が詰まらないので注意

> a = {1,2,3}
> a[2] = nil
> table.unpack(a)
1 nil 3
> a = {1,2,3}
> table.remove(a, 2)
2
> table.unpack(a)
1 3

idx 配列で exclude 処理

元配列の参照を変えないで行う

$ cat test.lua 
ar = {"a1", "a2", "a3", "a4", "a5", "a6"}
exclude = {"a2", "a4", "a5"}

cnt = 1
idx = 1
while (idx <= #ar) do
rm = false
for j, ex in pairs(exclude) do
if ar[idx] == ex then
table.remove(ar, idx)
rm = true
break
end
end
print(cnt, #ar, table.unpack(ar))
if not rm then idx = idx + 1 end
cnt = cnt + 1
end

$ lua test.lua
1 6 a1 a2 a3 a4 a5 a6
2 5 a1 a3 a4 a5 a6
3 5 a1 a3 a4 a5 a6
4 4 a1 a3 a5 a6
5 3 a1 a3 a6
6 3 a1 a3 a6

連想配列の要素数は保証されない

> ar = {a="a", b="b"}
> #ar
0

可変長引数 を table に変換

val = {...}
val = table.pack(...)

テーブルコンストラクタの最後の要素が変数列挙のとき 連結される

chain = {4 , 5}
val = {1, 2, 3, unpack(chain)}
print(unpack(val)) -- {1, 2, 3, 4, 5}

次のようにしても a 配列の中身は 1つしか返っていないので注意

> a = {1, 2, 3}
> b = {4, 5, 6}
> c, d, e, f, g, h = table.unpack(a), table.unpack(b)
> print(c, d, e, f, g, h)
1 4 5 6 nil nil

function の引数でも同じ

> a = {1, 2, 3}
> b = {4, 5, 6}
> function func(...) print(...) end
> func(table.unpack(a), table.unpack(b))
1 4 5 6

table を変数列挙に変換

print(unpack({1, 2, 3}))

lua 5.2 以降は table.unpack()

print(table.unpack({1,2,3}))

可変長引数

function log(...)
print(...)
end

2個目以降でも可

> function a(arg1, ...) print(arg1) print(...) end
> a(1, 2, 3)
1
2 3

配列の値に nil があると要素数が保証されない

"" , 0 などで初期化が無難

> ar = {nil, nil, nil}
> print(#ar)
0
> ar = {"", "", ""}
> print(#ar)
3
> ar = {0, 0, 0}
> print(#ar)
3

真偽値 ( condition )

nil と false 以外はすべて true

> if nil then print("true") else print("false") end
false
> if false then print("true") else print("false") end
false
> if 0 then print("true") else print("false") end
true
> if "" then print("true") else print("false") end
true

nil と false を区別したい場合は type() を見る

> a = nil
> if not a and type(a) == "nil" then print("a = nil") end
a = nil

> a = false
> if not a and type(a) == "boolean" then print("a = false") end
a = false

for 文

for i = 1, 10 do
end

lua に continue はありません

not の解釈で注意

if not val1 == val2 then
-- と書くと
-- if (not val1) == (val2) then -- と評価される
-- if not (val1 == val2) then -- ではないので注意

table のコピー

new_tbl = {unpack(org_tbl)}

table へ要素を追加

table.insert(t, val)  -- t:table, val:追加する値

table の要素を削除

table.remove(t, idx)  -- t:table, idx:index

ゼロパディング

string.format("%03d", i)

小数の切り捨て表示

> val = 123.456
> print(string.format("%7.2f", val))
123.46

-- 7 は . も入れた全体の文字数
-- 小数切り捨てはおおむね四捨五入のようだが厳密でないときもある

複数行コメントアウト

--[[
コメントアウト部分
--]]

コメントアウト部分を実行部分に戻すには
開始側を

---[[

とするだけで手軽に切り替えられる
終了側を編集する必要はない

変数の型を見る

type() を使う

print(type(val))  -- val は変数

ランダム値を得る

math.randomseed() をしても最初の math.random() はランダム値にならない
仕様のようなので1回ダミーで math.random() を実行する
2回目以降はランダム値が得られます

math.randomseed(os.time())
math.random(1, 2) -- dumy, 1回目はランダム値が得られないため
math.random(1, 10) -- 1 - 10 のいずれかの整数を得る

table の内容を出力する (1次配列)

pairs() を使う

local tbl = {5,4,3,2,1}
for key, val in pairs(tbl) do
print(key, val)
end

unpack() を使う

local tbl = {5,4,3,2,1}
print(unpack(tlb))

ただし unpack() は idx 配列にのみ有効

> a = {a = "a", b = "b", 3}
> print(table.unpack(a))
3

defold であれば pprint() を使ってもよい

a = {a = "a", b = "b", c = "c", 1 , 2, 3}
pprint(a)

DEBUG:SCRIPT:
{
1 = 1,
2 = 2,
3 = 3,
b = b,
a = a,
c = c,
}

変数名 _ (アンダースコアのみ) も変数として使える

> _ = 1
> print(_)
1

ダミー変数に使うとよい

table sort

sort は sort 関数を用いて sort する

ゲームづくりの 数学 基礎 メモ

ooq.kamui

ゲームを実装しているときに考えた 数学の基礎知識 について すぐ忘れてしまうので, メモを書いていきます

3D の回転とかじゃなくてもっと初級の高校生レベルのものとなります

プログラムを利用する場合は lua ( defold ) となります

ラジアン

角度の単位

半径 1 の円の円弧の長さで示される角度

180度が π ラジアン

360度が 2π ラジアン

プログラムでは基本的に角度はラジアンを用いる

π

円周率

直径に対する円周の比率
つまり, 直径 1 の円の円周の長さ

3.14159265... のこと

半径 1 の円周の長さは 2 π

sin ( サイン )

注) sin, cos, tan について, 位置関係などは 図解入りの wikipedia などを参照

ある角度に対して 直角三角形 を想定し, その 斜辺の長さ に対する 高さ(縦の長さ) の比

比なので 直角三角形 の大きさは問わない

そこで, 斜辺を半径 1 の円の半径にあてはめてみると, 次のように読みとれる

角度を半径 1 の円の座標で表したときの y 座標

角度に対して, その単位ベクトルの y 座標

cos ( コサイン )

ある角度に対して 直角三角形 を想定し, その 斜辺の長さ に対する 底辺(横の長さ) の比

比なので 直角三角形 の大きさは問わない

そこで, 斜辺を半径 1 の円の半径にあてはめてみると, 次のように読みとれる

角度を半径 1 の円の座標で表したときの x 座標

角度に対して, その単位ベクトルの x 座標

tan ( タンジェント )

注) tan は本質的にはここでそれほど重要ではありませんが念のため記述

ある角度に対して 直角三角形を想定し, その 底辺(横の長さ) に対する 高さ(縦の長さ) の比

比なので 直角三角形 の大きさは問わない

角度を x, y 座標で示したときの y / x の値

座標から角度を得る

上述のように sin, cos を用いれば 角度を 半径 1 の円の座標で表すことができる

というよりも, ここまで学習すると, 角度 と 座標 を橋渡しするために考案されたものが sin, cos であったのだと 逆に分かってくる

マイナス座標も考慮し, x, y 座標(cos, sin) を組み合わせると, 角度から座標の対応は一意に決まる
よって 座標から角度への逆変換も可能である

この逆変換を行う関数が arc sin, arc cos ( アークサイン, アークコサイン ) となる

プログラムではふつう atan2(y, x) を使う

関数名がアークタンジェントだが, これは内部的には arc sin, arc cos の組み合わせからの算出 と思われる

つまり, 関数名が アークタンジェント であるものの, 内部的は atan( y / x ) で求めているわけではないはず

なぜなら atan2() は一意に決まるため
atan() は一意には決まらない
180度逆の角とどちらか不確定となる

> math.atan2(0, -1)
3.1415926535898

座標から 単位ベクトルを得る (平面)

上述のように座標から角度を得ることはできるので, その角度の cos, sin を取れば単位ベクトルとなる

三角関数を用いず, 三平方の定理から斜辺の長さを取って, その比で求めてもよい

$ cat unit_vec.lua 
x = 3
y = 4
r = math.atan2(y, x)
ux = math.cos(r)
uy = math.sin(r)
print(ux, uy)

z = math.sqrt(x^2 + y^2)
ux = x / z
uy = y / z
print(ux, uy)

$ lua unit_vec.lua
0.6 0.8
0.6 0.8

lua 学習リンク

ooq.kamui

lua 学習用に見つけたページを記載していく

高速スクリプト言語 [Lua] を始めよう
http://www.ie.u-ryukyu.ac.jp/~e085739/lua.hajime.html

C/C++ 言語プログラマのための Lua 入門リファレンス
https://qiita.com/dwarfJP/items/e033728f5cbecbabe11f

Lua 5.2 リファレンスマニュアル
http://milkpot.sakura.ne.jp/lua/lua52_manual_ja.html

Luaプログラミング入門
https://densan-labs.net/tech/lua/

備忘録Lua
https://qiita.com/nagtos/items/76c7b195ad8cf2d4857d

Lua Memo
http://aoikujira.com/wiki/lua/

sed メモ

ooq.kamui

すぐ忘れるのでメモをどんどん書いていく

環境はすべて mac です

別ファイルの内容を差し込む

sed "/key/ r file.txt"

key の行の下の行に差し込まれます
key の行は消えません

位置指定: 最後の行

sed "$ s/find/replace/g"

位置指定: m 行目から n 行目

sed "m,n s/find/replace/g"

位置指定: key1 のある行から key2 のある行

sed "/key1/,/key2/ s/find/replace/g"

位置指定: key のある行

sed "/key/ s/find/replace/g"

実行結果を入力ファイルに上書き保存する

sed -i '' -e "s/xxxx/yyyy/g" filename.txt

vim メモ

ooq.kamui

自分用のメモです

環境はすべて mac です

別の syntax highlight ファイルを適用する

例えば lua で default 設定とは別に どこかから download した syntax highlight ファイル lua.vim を設定したい場合

~/.vim/syntax

の下に lua.vim を置く

単語選択

viw

mac の vim で tab を入力する

入力モードにする
ctl-v
<tab>

ファイルパスを新しいタブで開く

ctl-w gf

標準出力を vim で見る

cat filename | vim -

コマンドラインから tab で開く

vim -p *.txt

tab で開く

:tabnew [filename]

次のタブ

gt

前のタブ

gT

確認しながら置換

:%s/find/replace/gc

カーソル行から最後の行まで削除

dG
V
G
d

複数行の行末に文字追加

ctl-v
j などで行選択
$
A

カレント行に貼り付け

P

行選択モード

V

box 選択モード

ctl-v

redo

ctl-r

カーソル行に行追加して入力モード

O

bash スクリプト メモ

ooq.kamui

シェルスクリプト メモ のうち, bash のものをこちらに書いていきます

環境はすべて mac です

標準出力をまとめる

{
command1
command2
} > output.txt

mac terminal メモ

ooq.kamui

すぐ忘れるのでメモをどんどん書いていく

mac 特有のものをこちらに記載していきます

標準出力をクリップボードに copy (mac)

pbcopy

シェルスクリプト メモ

ooq.kamui

すぐ忘れるのでメモをどんどん書いていく

シェルスクリプト全般, unix 全般のものを記載していきます

環境はすべて mac です

ファイルの初期化

: > tmp.txt

seq のゼロパディング

seq -f "%03g" 1 10

シェル変数のゼロパディング

printf "%03d" $i

cat に行番号をつける

cat -n

改行を含んでいるシェル変数の中身を改行を保持したまま出力する

echo "$val"

m 行目から n 行目を得る

sed -n "m,n p"
awk "m&lt;=NR && NR&lt;=n"

ファイル名の一括変換

ls | while read f; do mv $f ${f/find/replace}; done

ディレクトリ配下ぜんぶ見る

ll -R
find .

各ディレクトリ配下の合計サイズを見る

du -hd1 .

日付のフォーマット指定

date "+%Y%m%d_%H%M%S"

ディレクトリ構造そのままにファイルは全部シンボリックリンク

ooq.kamui

ディレクトリ構造そのままに ファイルは全部シンボリックリンクでコピーをしたいとき ありませんか?

わたしはあります
ちょっと何言ってるか分からないかもしれませんが

そんなわけでそういうシェルスクリプトを作成しました

環境は mac です

cp_ln.sh
{{< gist ooq-kamui 4fadcc1d5bf9cbf06bfceb518864dd89 >}}

プログラム中にコメントで説明を入れています