conf t

インフラエンジニアのメモ

Windowsでfind / grep

Windowsでfind / grep 使えないか

find . -type f | xargs grep "検索したい文字列"的なことをWindowsでもできないか調べました。

PowerShellである程度似たことはできます。
コマンドは以下になります。

ls -r | Select-String "探したい文字列"

日本語を検索したい場合
ls -r | Select-String "探したい文字列" -Encoding default

実行例

PS E:\unity\ShootingGame\Assets> ls -r | Select-String "speed"

Animations\Enemy\Enemy.controller:32:  m_Speed: 1
Animations\Explosion\Explosion.controller:32:  m_Speed: 1
Animations\Player\Player.controller:32:  m_Speed: 1
Prefabs\Enemy.prefab:184:  speed: .5
Prefabs\EnemyBullet.prefab:73:  speed: 2
Prefabs\PlayerBullet.prefab:162:  speed: 10
Prefabs\Wave.prefab:565:  speed: .5
Prefabs\Wave.prefab:581:  speed: .5
Prefabs\Wave.prefab:608:  speed: .5
Scenes\Stage.unity:31:  m_FlareFadeSpeed: 3
Scenes\Stage.unity:355:  speed: .0199999996
Scenes\Stage.unity:551:  speed: 5
Scenes\Stage.unity:826:  speed: .100000001
Scenes\Stage.unity:1002:  speed: .0799999982
Scripts\Background.cs:6:    public float speed = 0.1f;
Scripts\Background.cs:11:        float y = Mathf.Repeat (Time.time * speed, 1);
Scripts\Bullet.cs:6:    public int speed = 10;
Scripts\Bullet.cs:14:        GetComponent<Rigidbody2D>().velocity = transform.up.normalized * speed;
Scripts\Enemy.cs:40:        GetComponent<Rigidbody2D>().velocity = direction * spaceship.speed;
Scripts\Player.cs:54:        pos += direction * spaceship.speed * Time.deltaTime;
Scripts\Spaceship.cs:8:    public float speed;

lsはGet-ChildItemのエイリアスです。Get-Aliasで確認できます。

PS E:\unity\ShootingGame\Assets> Get-Alias ls

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Alias           ls -> Get-ChildItem

Select-Stringじゃなくて、grepと打ちたい!

Select-Stringを毎回打つのはしんどいので、エイリアスを登録します。

Select-Stringのエイリアスgrepを作成します。

PS E:\unity\ShootingGame\Assets> Set-Alias -name grep -value Select-String
PS E:\unity\ShootingGame\Assets> Get-Alias grep

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Alias           grep -> Select-String

はい、これで出来ました。
Set-Aliasは引数の順序を間違えないように、慎重に実行してください。
例えばnameとvalueを逆にすると、Select-Stringと打つとgrepという、 存在しないコマンドを実行しようとするので、select-stringが実行できなくなります。

その場合は、

Remove-Item Alias:\Select-String

で間違えて登録したエイリアスを削除してください。

PS E:\unity\ShootingGame\Assets> ls -r | grep "speed"

Animations\Enemy\Enemy.controller:32:  m_Speed: 1
Animations\Explosion\Explosion.controller:32:  m_Speed: 1
Animations\Player\Player.controller:32:  m_Speed: 1
Prefabs\Enemy.prefab:184:  speed: .5
Prefabs\EnemyBullet.prefab:73:  speed: 2
Prefabs\PlayerBullet.prefab:162:  speed: 10
Prefabs\Wave.prefab:565:  speed: .5
Prefabs\Wave.prefab:581:  speed: .5
Prefabs\Wave.prefab:608:  speed: .5
Scenes\Stage.unity:31:  m_FlareFadeSpeed: 3
Scenes\Stage.unity:355:  speed: .0199999996
Scenes\Stage.unity:551:  speed: 5
Scenes\Stage.unity:826:  speed: .100000001
Scenes\Stage.unity:1002:  speed: .0799999982
Scripts\Background.cs:6:    public float speed = 0.1f;
Scripts\Background.cs:11:        float y = Mathf.Repeat (Time.time * speed, 1);
Scripts\Bullet.cs:6:    public int speed = 10;
Scripts\Bullet.cs:14:        GetComponent<Rigidbody2D>().velocity = transform.up.normalized * speed;
Scripts\Enemy.cs:40:        GetComponent<Rigidbody2D>().velocity = direction * spaceship.speed;
Scripts\Player.cs:54:        pos += direction * spaceship.speed * Time.deltaTime;
Scripts\Spaceship.cs:8:    public float speed;

ただこれだと複数行にmatchさせる正規表現はつかえないっぽいです (powershellがファイルの各行を配列に格納している?)

日本語を検索したい場合

日本語を検索する場合、powershell文字コードUTF-16なのでうまくいきません。
末尾に-Encoding defaultオプションを付与して実行することで、日本語も検索できます。

ls -r | Select-String "探したい文字列" -Encoding default

余談

あと豆知識ですが、探し物をしたいディレクトリまでエクスプローラで移動して、
アドレスバーにpowershellでエンターすると、初期位置がそのディレクトリになるので、
素早くコマンドを実行できます。

f:id:monaski:20150528221930j:plain