perl rename: サブディレクトリのファイル名セットの前に何かを追加します。

perl rename: サブディレクトリのファイル名セットの前に何かを追加します。

perlこのツールは日常業務で非常に貴重な仲間になりましたが、rename作業をより困難にするいくつかの欠点がまだあります。特にファイルがある場合はさらにそうです。いいえ現在作業ディレクトリにあります。

請求書が多く、customer1 のすべての請求書が 1 つのアカウントに割り当てられていることがわかっているとします。したがって、将来のスクリプトを簡単にするために、assi_「割り当て済み」を前に追加したいと思います。

たとえば、

/home/user/bizz/invoices $ ls -1 t1/inv*

t1/inv_customer1_20130506.txt
t1/inv_customer1_20130823.txt
t1/inv_customer1_20130930.txt
t1/inv_customer2_20131207.txt
t1/inv_customer2_20131113.txt

今何が起こるのか見てみましょう。

/home/user/bizz/invoices $ rename 's/^/assi_/' t1/inv_customer1*

Can't rename t1/inv_customer1_20130506.txt assi_t1/inv_customer1_20130506.txt: No such file or directory
(etc.)

へへ。rename すでに選択済みフルパスassi_ファイルだけでなくファイルに追加する前に使用されます。だから私は見つけることができません。inv_customer1_20130506.txt存在しない目次「assi_t1」。

renameそれでは、ファイル名にのみ正規表現を適用するように教える方法は何ですか?

注:
1.常にサブディレクトリに移動したくありませんcd。 2.
可能であればループの使用も避けますfind

答え1

renameディレクトリ間でファイルを移動できるため、このように動作します。同様に、mv最後のコンポーネントだけでなく、フルパスで動作します。

最後のコンポーネントのみを変更したい場合は、正規表現を に固定し、一致するものがなく、最後のコンポーネントにのみ(\A|?<=/)一致することを確認できます。//

rename 's~(\A|?<=/)(?=[^/]*)\z~assi_~' t1/inv_customer1*

もう一つの方法は、ファイル名を最初に分割することです。

rename 's~(.*/)~~s; my $d = $1; s/\A/assi_/; $_ = "$d$_"' t1/inv_customer1*

このモジュールを使用することもできますFile::Spec。これはUnix以外のパスを処理する利点があります。

rename 'use File::Spec::Functions; my ($v,$d,$f) = splitpath($_); $f =~ s/\A/assi_/; $_ = catpath($v,$d,$f)' t1/inv_customer1*

関連情報