現在、スペースと特定の名前を削除してファイル名を変更するスクリプトがあります。これまでに約200の名前があるので、除外する名前の配列がより良い選択になると思いました。
prename -v 's/ /_/g' *
prename -v 's/_-_/_/g' *
prename -v 's/_\(Summer-HD\)//ig' *
prename -v 's/_\(Hammer\)//ig' *
prename -v 's/_\(Hardware-Hybrid\)//g' *
prename -v 's/_\(digital\)//ig' *
prename -v 's/_\(Resolution-SD\)//ig' *
これまで試したことは、除外したい名前を繰り返すforループですが、うまくいきませんでした。
exclude=('(Summer-HD)' '(Hammer)' '(digital)' '(Resolution-SD)' '(Vacation)' '(Hammer-Hybrid)')
for x in "${exclude[@]}";
do prename -v 's/$x/_/g' * {} \;
done
この for ループはまったく機能せず、点滅するカーソルだけが残ります。 prenameに変数を渡すことができるかどうかはわかりません。二重引用符の使用に関するいくつかの提案に基づいて、forループをいくつか修正しました。
for x in "${exclude[@]}";
do prename -v 's/$x/_/g' *"$x"* {} \;
done
これもうまくいかず、ここで何が起こっているのかわかりません。現在削除したい名前が200を超えるので、まだ名前の配列が必要です。名前に関しては、私はその考えに同意しません。 sed や awk が役に立つと聞いた。私はそうしたくありません。提供できるアイデアや助けに感謝します。
答え1
スクリプト内で配列(またはリストで構成された正規表現を含むスカラー変数)を定義できますprename
。辞書名スクリプト内で有効なPerlコードを使用できることに注意してください。はい特別なPerlスクリプト)。例えば
$ touch foo_\(Summer-HD\)_\(digital\).mkv
$ prename -n 'BEGIN {
our $exclude=join("|", qw(Summer-HD Hammer digital Resolution-SD Vacation Hammer-Hybrid));
};
our $exclude;
s/_\((?:$exclude)\)//ig;' *
rename(foo_(Summer-HD)_(digital).mkv, foo.mkv)
ここに注目すべきいくつかの点があります。
- 変数のスコープは名前変更スクリプトで非常に重要であり、
use strict
プラグマが適用されます。視聴してくださいperldoc strict
(もっと内容がありますが、簡単に言うと:strict
現在の範囲で以前に宣言されていなかった変数は使用できません。 - 変数は、ファイル名ごとに1回ではなく、スクリプトが実行されたときに1回だけ実行されるように
$exclude
ブロックに定義されています。BEGIN {}
これには、文字で連結された配列、|
つまり正規表現の置換が含まれます。 our
BEGINブロック外で共有できるように変数として定義されます。つまり、File::Rename
パッケージの範囲全体で使用できます。これはおそらくあなたが知りたい以上のものなので、名前変更スクリプトのグローバル変数と考えることができます。メインコードブロックもこれを宣言する必要があります(のみ使用されますour $exclude;
)。バラよりperldoc -f our
qw()
スペースで区切られた単語のリストを配列に変換するPerlの参照演算子の1つ。望むよりperldoc -f qw
。ところで、Perlでは、「配列」と「リスト」はほぼ同義です。perldoc -q difference.*list.*array
rename
複数回実行するのではなく、1回実行するには長いスクリプト(または複数のオプション)を使用する必要があることにも注意する価値があります-e '...script...'
。例えば
$ prename -n 'BEGIN {
our $exclude=join("|", qw(Summer-HD Hammer digital Resolution-SD Vacation Hammer-Hybrid));
};
our $exclude;
s/ /_/g;
s/_-_/_/g;
s/_\((?:$exclude)\)//ig;' *
答え2
以下を使用する方が簡単ですzsh
。
exclude=(
'(Summer-HD)'
'(Hammer)'
'(digital)'
'(Resolution-SD)'
'(Vacation)'
'(Hammer-Hybrid)'
)
pattern="_(${(j[|])${(b@)exclude}})"
autoload -Uz zmv
zmv '*' '${f//$~pattern}'
これは${(b)exclude}
要素のグローバル演算子をエスケープし$exclude
て${(j[|])...}
結果を結合するので、最終的にはbeing(具体的には:)|
で終わり、一括renamer内でksh93の演算子を使用して一致をnullに置き換えます。$pattern
_(exclude1|exclude2...)
_(\(Summer-HD\)|\(Hammer\)|\(digital\)|\(Resolution-SD\)|\(Vacation\)|\(Hammer-Hybrid\))
${f//pattern[/replacement]}
zmv