ファイル拡張子を再帰的に見つけて変更するBashスクリプト

ファイル拡張子を再帰的に見つけて変更するBashスクリプト

特定の拡張子(または)を持つディレクトリ内の.pngすべてのファイルのファイル拡張子を変更する小さなスクリプトを作成したいと思います.gif

私の考えは、スクリプトが実行されるときに2つのパラメータしか必要ないということです。 1つ目は変更したい拡張子、2つ目は変更したい拡張子です。

最初はそれを使用してターゲットディレクトリをインポートすると思いましたが、複雑すぎてread現在のディレクトリで動作するようにしました。 Debian 9を実行しているため、このrenameコマンドは使用できません。

これは固定コンテンツ(txtからrdfまで)に適用されます。

$ find -depth -name "*.txt" -exec sh -c 'mv "$1" "${1%.txt}.rdf"' _ {} \;

しかし、渡されたパラメータを継承する変数の内容の拡張子をどのように変更するのかわかりません。デフォルトでは $1 $2 ですが、次のように変更しても機能しません。

$ find -depth -name "*.$1" -exec sh -c 'mv "$1" "${1%.$1}.$2"' _ {} \;

この例では、一致するすべてのファイルの末尾に 。私がここで何を見逃しているのでしょうか?

答え1

#!/bin/sh

find . -depth -name "*.$1" -exec sh -c '
    from=$1
    to=$2
    shift 2
    for pathname do
        mv "$pathname" "${pathname%.$from}.$to"
    done' sh "$1" "$2" {} +

これにより、内部スクリプトは、変更するパス名のリストとともにファイル名サフィックスを引数として使用できます。内部スクリプトでは、2つのサフィックスを抽出してパラメータリストから移動しますfind

それほど効率的ではありません(sh -cパス名の配置を繰り返すのではなく、パス名ごとに1回呼び出されます):

#!/bin/sh

find . -depth -name "*.$1" -exec sh -c 'mv "$3" "${3%.$1}.$2"' sh "$1" "$2" {} ';'

参考までに、内部スクリプトのゼロ番目の引数として、shまたは他の関連名を使用する習慣を入れてください。find-shこのパラメータはスクリプトのエラーメッセージに使用され、_場合によってはエラーメッセージのソースが混乱する可能性があります。

関連情報