ファイル名の1つのコンポーネントを変更して複数のファイルの名前を変更するには?

ファイル名の1つのコンポーネントを変更して複数のファイルの名前を変更するには?

コマンドラインを使用して複数のファイルの名前を変更する方法について多くの質問を見つけました。ただし、このファイル名を変更する特定の問題は解決できません。

something_4M_something_something_manyothersomethings.csv

以下を入力してください:

something_4_M_something_something_manyothersomethings.csv

私に必要なのはフィールドを分割することですが、4Mそう4_Mすることはできません(注:各下線で区切ると、タスクにとって重要ではない他のフィールドがたくさんあります。

私がしたことは次のとおりですが、期待どおりに動作しません。正規表現に問題があるようですが、より良い方法が見つかりません。

rename -n 's/.4M/$&_4_M/' *

また、このような質問の1つのコメントで似たようなものを見つけましたが、もはや見つからないので、私が書いたものが正確にどのように機能するのかわかりません。

答え1

本当にあなたが望むもの4Mに置き換えるものであれば、4_M正規表現のバリエーションで次のことができます。

$ ls
something_4M_something_something_manyothersomethings.csv
$ rename -n 's/4M/4_M/' *
'something_4M_something_something_manyothersomethings.csv' would be renamed to 'something_4_M_something_something_manyothersomethings.csv'

正規表現は何でも機能します。~へ名前なので、先行する「何か」を維持するために特定のタスクを実行する必要はありません。

4M最初の「何か」を2番目の「何か」に移動したり、下線の後の最初の項目に制限するなど、他の作業を実行するには、質問を編集して明確にします。


コメントに示されているように、-n練習の実行が行われ、何が起こるかを示し、実際には何もしません。

質問の例はすでに使用されているので、-n質問者がこれを理解できると仮定します。

答え2

Raku(以前のPerl_6)の使用

単一ファイルの場合:

    ~$ raku -e ' \
    my $name = dir(test => /^ something_4M_somethingelse \. csv $/)[0]; \
    my $modname = S/^ something_<(4M)>_somethingelse \. csv $/4_M/.IO given $name; \
    ($name,$modname).say; \
    #rename($name,$modname, createonly => True);'

複数のファイルの場合:

    ~$ raku -e ' \
    my @names = dir(test => /^ something_<digit><upper>_somethingelse \. csv $/); \
    my @modnames = do for @names {S/^ something_<(<digit><upper>)>_somethingelse \. csv $/$<digit>_$<upper>/.IO given $_;}; \
    for [Z] @names,@modnames -> ($x,$y) { ($x,$y).say }; \
    #for [Z] @names,@modnames -> ($x,$y) { rename($x,$y, createonly => True) };'

ディレクトリ入力:

~$ ls
something_4M_somethingelse.csv  something_5N_somethingelse.csv  something_6O_somethingelse.csv

ディレクトリ出力(複数のファイル名を変更):

~$ ls
something_4_M_somethingelse.csv something_5_N_somethingelse.csv something_6_O_somethingelse.csv

警告する:まずバックアップしてください! !

簡単な説明(単一ファイルの名前変更):dir()正規表現の一致(「副詞」)オプションを使用して興味のあるファイルのリストを取得し、1つの要素test => / ... /(何でも[0])をインポートしてスカラー変数に保存します$name。変数を確認すると、その変数がオブジェクトであることがわかります.IO

おなじみのイディオムを使用して変数をS///変更しgiven $name、変更された名前をとして保存します$modname。ここではS///文字列化された so.IOメソッド呼び出しが追加され、S///that も$modnameオブジェクトになります.IO

正規表現では、慣れていない記号が<(…)>表現である可能性があります。でもそれは楽のことだけだキャプチャマークそのため、左半分の完全一致がS///認識されるのに対し、右半分では4Mその中の一致のみがキャプチャされ修正されます。<(…)>S///

.IO必要な開始/終了オブジェクトを取得した場合、この行は次のよう($name,$modname).say;な出力を生成する必要があります。

("something_4M_somethingelse.csv".IO "something_4_M_somethingelse.csv".IO)

すべてが大丈夫に見える場合は、Rakuコードの最後の行rename()のコメントを外して、実際に最後から2番目の行にリストされているファイル名を.say

注:上記のコードcreateonly => Trueに副詞/オプションを含めると、既存のファイル名は削除されません(短い形式でも同じ効果があります)。デフォルト値(破壊など)を取得し、既存のファイル/ファイル名の名前変更(上書き)を許可するには、副詞/オプションを削除または削除します。rename()rename():createonlycreateonly => True:createonlyFalse

https://docs.raku.org/syntax/S$SOLIDUS$SOLIDUS$SOLIDUS
https://docs.raku.org/routine/rename
https://raku.org

関連情報