1. ホーム
  2. bash

[解決済み] find と sed を使って再帰的にファイル名を変更する

2023-03-27 20:14:07

質問

私はディレクトリの束を調べて、_test.rb で終わるすべてのファイルを、代わりに _spec.rb で終わるように名前を変えたいと思います。それは、私が bash で行う方法を決して理解しなかったことなので、今回は、それを釘付けにするためにいくつかの努力をしようと思いました。しかし、私は今のところ、私の最高の努力は不足しています。

find spec -name "*_test.rb" -exec echo mv {} `echo {} | sed s/test/spec/` \;

注:execの後にechoが追加されていますが、これはテスト中にコマンドが実行されるのではなく、表示されるようにするためです。

実行すると、一致した各ファイル名の出力は次のようになります。

mv original original

というように、sedによる置換が失われています。何かコツがあるのでしょうか?

どのように解決するのですか?

この現象は sed は文字列 {} で確認できるように、入力として受け取ります。

find . -exec echo `echo "{}" | sed 's/./foo/g'` \;

と表示されます。 foofoo を表示します。この動作の理由は、パイプラインはシェルがコマンド全体を展開する際に一度だけ実行されるからです。

を引用する方法はありません。 sed のような形でパイプラインを引用する方法はありません。 find はすべてのファイルに対して実行されます。 find はシェル経由でコマンドを実行せず、パイプラインやバッククォートの概念も持っていないからです。GNU findutils マニュアルでは、パイプラインを別のシェル スクリプトに置くことによって同様のタスクを実行する方法を説明しています。

#!/bin/sh
echo "$1" | sed 's/_test.rb$/_spec.rb/'

(何か変な使い方があるかもしれませんが sh -c と大量の引用符を使うことで、1つのコマンドでこれらすべてを行うという、何か変な方法があるかもしれませんが、試すつもりはありません)。