202


gitリポジトリ内の全erbファイルをhamlにリネームしたいです。（例: index.html.erb => index.html.haml）

以下のようなコマンドで一つずつリネームするのは大変です。

[code]

    $ git mv app/views/pages/index.html.erb app/views/pages/index.html.haml
    
[/code]

また、こんなコマンドが使えるかなと思ったのですが、無理でした。

[code]

    $ git mv app/views/**/*.erb app/views/**/*.haml
    
    usage: git mv [options] <source>... <destination>
    
        -n, --dry-run         dry run
        -f, --force           force move/rename even if target exists
        -k                    skip move/rename errors
    
[/code]

こういう場合はどうすればよいでしょうか？


CC BY-SA 3.0
2014-11-25T22:54:16.260
190
2014-12-19T04:11:00.367
85
question
git
gitで複数のファイルを一括で移動またはリネームする方法を教えてください


おそらくやりたいことは、単なるリネームでは無くてERBからHAMLへの移行だと思います。

[erb2haml](https://github.com/dhl/erb2haml) を導入した後、

[code]

    rake haml:replace_erbs
    git add --all
    
[/code]

とすると、ERBからHAMLに変換した後、レポジトリから *.erb を削除、*.haml を追加することができます。


CC BY-SA 3.0
2014-11-26T02:24:36.420
193
2014-11-26T02:24:36.420
76
190
answer


質問者と同じく[英語版サイトの解答](https://stackoverflow.com/a/9151943/4037)を入れると

[code]

    for i in $(find . -iname "*.erb"); do
        git mv "$i" "$(echo $i | rev | cut -d '.' -f 2- | rev).haml";
    done
    
[/code]

ですが、これだけだと価値を足していないので、解説してみます。

[code]

    $(find . -iname "*.erb")
    
[/code]

で、`.erb` で終わるファイルをすべてリストアップします。それを `for` で1つずつ見ていきます。

次に

[code]

    $(echo $i | rev | cut -d '.' -f 2- | rev)
    
[/code]

を見ていきます。

[code]

    echo $i | rev
    
[/code]

でファイルへのパスを逆向きにします（例：`app/views/person/index.html.erb` ->
`bre.xedni/nosrep/sweiv/ppa`）。

[code]

    cut -d '.' -f 2-
    
[/code]

で、ファイルをドット `.` で区切り、2番目以降だけ取り出します（つまり、`bre.` だけ消す）。

最後に `rev` で文字を元の正方向に戻します。（例：`xedni/nosrep/sweiv/ppa` ->
`app/views/person/index`）

これで

[code]

    git mv "$i" "$(echo $i | rev | cut -d '.' -f 2- | rev).haml";
    
[/code]

は元のファイル名から `.erb` だけ削り、`.haml` を加えて、`git mv` に渡すって感じになります。


CC BY-SA 3.0
2014-11-27T06:47:13.870
202
2014-11-27T06:47:13.870
2017-05-23T12:38:55.307
-1
41
190
answer


(私のように) `for` 文のどこにセミコロンを入れたらいいか覚えられない場合は xargs が使えます。

[code]

    find . -iname "*.erb" -not -path './vendor/*' \
      | rev | cut -d. -f2- | rev | xargs -IF git mv F.erb F.haml
    
[/code]

実行前に何が起こるか確認するには、最後に -n 引数を入れるか、echo を git mv の前に入れます。

[code]

    find . -iname "*.erb" -not -path './vendor/*' \
      | rev | cut -d. -f2- | rev | xargs -IF echo git mv F.erb F.haml
    
[/code]


CC BY-SA 3.0
2014-11-29T04:57:05.473
203
2014-11-29T04:57:05.473
30
190
answer


こういう明らかに ruby がインストールされている環境では、 ruby を使うと簡単だと思います。

[code]

    % ruby -e 'Dir.glob("app/views/**/*.erb") { |n| `git mv #{n} #{n.gsub(/erb$/,"haml")}` }'
    
[/code]


CC BY-SA 3.0
2014-12-02T01:46:09.040
216
2014-12-02T01:46:09.040
290
190
answer


自分の経験からなんですが、ファイル名変更のみの作業で `git mv` は必要ありません。というのは git
は、パスやファイル名からではなく、ファイルの中身で、ファイルの位置を認識・検知するからです。 ですから、「
_ファイルの中身を大きく変更せずに、拡張子だけを変更したような場合_ 」には、普通にしていれば、まあ、大抵は、「 **ファイル名を変更したと自動検知**
」されます。

ですので、この質問への答えは、「気軽にファイル名を変更して、`git add . -A` する」かな。

具体的な方法ですが、ファイル名の変更自体はどんなやりかたでもよく、例えば:

[code]

    find app/views -name "*.erb" -exec rename .erb .haml \{\} \;
    
[/code]

もしくはシステムによっては:

[code]

    find app/views -name "*.erb" -exec rename 's/.erb$/.haml/g' \{\} \;
    
[/code]

として作業を終えた後:

[code]

    git add . -A
    git status
    
[/code]

とします。名前変更されたファイルは、renamed として認識されるはずです。 (`-A` オプションで add/rm を同時に行なわせるのが重要です )
ファイルの変更があまり大きくない場合は、これで事足りるでしょう。

**補足** : サブディレクトリを対象にせず、そのディレクトリのファイルの名前を変更するだけならば、

[code]

    rename .erb .haml *.erb
    git add . -A
    
[/code]

もしくは、

[code]

    rename 's/.erb/.haml/g' *.erb
    git add . -A
    
[/code]

で済みます。


CC BY-SA 3.0
2014-12-19T04:05:26.643
2091
2014-12-19T04:11:00.367
2014-12-19T04:11:00.367
4978
4978
190
answer