web-dev-qa-db-ja.com

同じ名前の異なるディレクトリにあるファイルの名前を変更して、それぞれが一意の(番号付きの)名前を持つようにします

複数のサブフォルダーの内容をHDDにコピーできるように、SDカードのファイルの名前を変更する必要があります。まず、拡張子.MODでそれらを見つける必要があります(別のディレクトリにあるので、find ./path/*.MOD2を使用して検索できます)。

それらはすべてMOV001.MODMOV002.MODのような名前を持っているため、名前を変更する必要があります。これは私のカメラによって作成されました。名前を変更した後、1つのコマンドでHDDにコピーできました。

実際の名前のため、cp ./path/*.MOD new-pathを使用すると、同様の名前のファイルが上書きされます。

どうすれば解決できますか?

3
Mikulas Kuzmiak

この小さなスクリプトは、ファイルを移動せずに名前を変更します

n=0; for files in dir1/*.MOD dir2/*.MOD dir3/*.MOD; do printf -v new "${files/MOV*./%02d.}" "$((++n))"; echo mv -v "$files" "$new"; done

またはもっと読みやすい:

#!/bin/bash
n=0
for files in dir1/*.MOD dir2/*.MOD dir3/*.MOD; do
   printf -v new "${files/MOV*./%02d.}" "$((++n))"
   echo mv -v -- "$files" "$new"
done

dir1などを、ファイルのあるディレクトリへの実際のパスに置き換えます

実際にファイルの名前を変更するには、echo(テストするだけです)を削除して、必要なものが得られることを確認してください。

これにより、ファイル01.MOD02.MODなどに番号が付けられます。99個を超えるファイルがある場合は、%02d%03dに置き換えて001.MODなどを取得します。


説明:

n=0これは、n0に設定するだけです。これは、bashがカウントを開始する場所です。

for files in dir1/*.MOD dir2/*.MOD dir3/*.MOD

forループは、各ファイルに対して順番にコマンドを繰り返し実行できます。構文はfor [variable] in [these things I want to do something to] ; do [command(s)] $[variable]; done変数filesを呼び出し、globを使用してファイルを見つけました:*.MODは、シェルによって名前が.MODで終わる任意のファイルに拡張されます(*は任意の文字に一致します)

printf -v new

printfは、並べ替えを容易にするために、新しい幅を固定幅でフォーマットできます。 newは別の変数です-これはファイルの新しい名前です。

"${files/MOV*./%02d.}" "$((++n))"

以前の変数filesを参照し、MOV**は任意の文字であることを忘れないでください)を、インクリメントする数値$((++n))の結果に置き換えます(これは、スクリプトの最初の行のnです。ファイルでループが実行されるたびに1つずつ)コード%02dを使用してフォーマットされます。これは、printfが2桁の固定幅の10進数01、02などを意味します。検索および置換パターンには、停止する.が含まれます*はファイル名全体に一致し、そのため拡張子を削除します。

echo mv -v -- "$files" "$new"

テスト用にechoを追加します-これは、実際に実行する代わりに何が実行されるかを示しています。結果に満足したらエコーを削除して、実際にコマンドを実行します。

mvはファイルの名前を変更または移動します。構文はmv oldname newnameです。 mvに「verbose」であることを通知し、各アクションを報告する-vフラグを追加しました。安全のために--を追加しました-これはmvにそれ以上のオプションを受け入れないように指示し、-で始まるファイル名がコマンドのオプションとして解釈されないようにします。

files変数で指定された各ファイルは、mv変数で作成された一意の名前にnewedされます。 $を使用して変数を参照します。これらは「二重引用符」で囲み、シェルがファイル名に対して他の展開を行わないようにします。これにより、ファイル名の特殊文字またはスペースが問題を引き起こしなくなります。

3
Zanna

再帰的なディレクトリ(すべてのサブディレクトリを含む)からそれらをコピーし、拡張子を検索し、以下のスクリプトを使用して1つの手順で名前を変更できます。

再帰ディレクトリからファイルをコピーするときに、ファイルを上書きするnotを確認するために使用するスクリプトから取得:

#!/usr/bin/env python3
import os
import shutil
import sys

dr = sys.argv[1]
new_dir = sys.argv[2]

for root, dirs, files in os.walk(dr):
    for name in files:
        if name.lower().endswith(".mod"): # for your extension
            n = 1; name_orig = name
            while os.path.exists(new_dir+"/"+name):
                name = "duplicate_"+str(n)+"_"+name_orig
                n = n+1
            newfile = new_dir+"/"+name
            shutil.copy(root+"/"+name_orig, newfile)

スクリプトを空のファイルにコピーし、nodupes.pyとして保存し、入力(ソース)および出力ディレクトリを引数として実行します。

python3 /path/to/nodupes.py /path/to/sourcedir /path/to/outputdir

次のような同様の名前のファイルの名前を変更します。

enter image description here

もちろん、duplicate_の代わりに、番号が付けられたもの(または単に数字)を使用するようにスクリプトを変更できます。

1つの拡張機能のみを検索する一般的なバージョンnotは、次のようになります。

#!/usr/bin/env python3
import os
import shutil
import sys

dr = sys.argv[1]
new_dir = sys.argv[2]

for root, dirs, files in os.walk(dr):
    for name in files:
        n = 1; name_orig = name
        while os.path.exists(new_dir+"/"+name):
            name = "duplicate_"+str(n)+"_"+name_orig
            n = n+1
        newfile = new_dir+"/"+name
        shutil.copy(root+"/"+name_orig, newfile)
1
Jacob Vlijm