fishで複数ファイルをリネーム


fishは補完効きまくって好きなので使ってます

jade→pugに100ファイルぐらいリネームする機会がありまして
現在のディレクトリからサブディレクトリまでリネームしているのは見つからなかったので投稿します。

結論、このコードです

rename.sh
for jadefilepath in **.jade
  mv "$jadefilepath" (echo "$jadefilepath" | sed '$s/\.jade$/.pug/')
end

追記です

sed使うとわかりにくかったりするので、basenameで文字列を抜き出してという方法も書いておきます
こっちのほうが、正規表現をエスケープしないので、まだ見やすいかも(.jade→.pugに変換)

rename.sh
for filename in *.jade
  mv -v -- "$filename" (basename $filename .jade).pug
end 

参考サイト

TL;DR

(なんだTL;DRって)

  • .jade→.pugに拡張子を置換します

対象読者

  • fishを使用します
  • 今いる場所から、下に向かってひっかけて置換します

アウトプット

こういうディレクトリがあったとします
※treeコマンドで可視化してます

$ tree
.
├── current.jade
├── dir1
│   └── hoge1.jade
└── dir2
    ├── dir3
    │   └── hoge3.jade
    ├── dir4
    │   └── dir6
    │       └── hoge6.jade
    ├── dir5
    │   └── hoge5.jade
    └── hoge2.jade

6 directories, 6 files

さっきのコマンドを叩いて、

$ tree

.
├── current.pug
├── dir1
│   └── hoge1.pug
└── dir2
    ├── dir3
    │   └── hoge3.pug
    ├── dir4
    │   └── dir6
    │       └── hoge6.pug
    ├── dir5
    │   └── hoge5.pug
    └── hoge2.pug

6 directories, 6 files

サブディレクトリも含めて拡張子を.jade→.pugに変換することが出来ました。

インプット

自分のわかる範囲でコードを説明します

rename.sh
for jadefilepath in **.jade
  mv "$jadefilepath" (echo "$jadefilepath" | sed '$s/\.jade$/.pug/')
end
  1. for文で「.jade」が見つかる分だけ実行し、そのひっかけたパスを、jadefilepathに格納
  2. mvで変数$jadefilepathに格納したpathをmvコマンドでリネーム
  3. ()の中でsedコマンドを使って、.jade→.pugに置換(ここを参考にしました→How to rename file extentions in fish in a for loop?

1行目の**.pugでカレントディレクトリから下のサブディレクトリすべてワイルドカードでひっかけるのがミソですかね

カレントディレクトリのみを対象にしたい

1行目の**.jade*.jadeにしてアスタリスクをひとつ減らせばOKでした

fishのワイルドカード

カレントディレクトリのみの検索はアスタリスク1個

jadesearch.sh
$ ls *.jade

current.jade

サブディレクトリ含む検索はアスタリスク2個

jadesearch.sh

$ ls **.jade

current.jade              dir1/hoge1.jade           dir2/dir3/hoge3.jade      dir2/dir4/dir6/hoge6.jade dir2/dir5/hoge5.jade      dir2/hoge2.jade

参考

あとがき

fish普及計画を書いている人みたいに、熱中できる言語みつけたい