特定の種類のファイルを移動し、同じ名前のファイルの名前を変更します。

特定の種類のファイルを移動し、同じ名前のファイルの名前を変更します。

これが私が達成したいものです:

readpstライブラリを使用pstしてファイルを別のファイルに変換します.eml。各ファイルを変換した後、pst複数のサブディレクトリがネストされたディレクトリが作成され、各ディレクトリとサブディレクトリに.eml1..n

問題は、それらをすべて1つのディレクトリに配置する必要がありますが、次のように移動しようとすると次のようになります。

find . -name '*.zip' -exec mv --target-directory='/path/to/outputdir' '{}' +

同じ名前の項目を探して、次に終了します。

mv: will not overwrite just created 

競合しないようにファイルをディレクトリに移動して名前を変更する方法を知っている人はいますか?

ベストアンサー1

GNU実装には、ターゲットファイルがすでに存在する場合は別の名前でファイルを生成するオプションがcpあります。--backup=[CONTROL]バックアップ拡張子を区別するためにチルダ( "〜")を使用するため、フォーマットが少し見苦しくなります。

あなたにとって有用なCONTROL主張は次のとおりですnumbered

find . -name '*.zip' -exec cp --backup=numbered '{}' '/path/to/outputdir' \;

mvこのアプローチに従う場合は、後で別の手順で元のファイルを削除する必要があります。私はそのようなオプションを知らないからです。

このソリューションで私が見た問題の1つは、どのファイルがどのディレクトリから来たのかを区別する方法がないことです。編集:一部の人はこの動作が適切でブラウザのデフォルトの動作であると考えています(たとえば、同じ名前のファイルを同じディレクトリに複数回ダウンロードする場合)、この場合、これらの「バックアップ」のファイル拡張子は異なりますが、番号も付けられています。

上記に加えて、スラッシュ区切り文字をアンダースコアに変更するなど、各ファイル名にパスを挿入することもできます。結果はより多くの情報を提供しますが、エラーが発生する可能性があり、非常に長くて見苦しいファイル名が生成される可能性があります。

find . -name '*.zip' | while read filePath; do cp "$filePath" '/path/to/outputdir'/"$(echo "$filePath" | sed -e 's#^\\.##' -e 's#/#_#g')"; done

また、アンダースコアを含むファイルは実際には奇妙に見え、ファイル名の下線で区切られた部分が以前にパス名の一部であった場合、あいまいさが発生する可能性があります。

'/path/to/outputdir'! で始まるコマンド間のスラッシュ文字は"$(echo "$filePath" |...非常に重要です。

最初の表現は、sed検索ツリーの上部がドット文字で始まり、指定された場合に隠しファイルが生成されないようにすることです。find2 番目はパス区切り記号のスラッシュを下線で置き換えます。

また、このソリューションはスケーラブルではありません。クエリだけを変更したい場合は、重大な結果を避けるために多くの変更を行う必要があるかもしれませんfind。たとえば、findクエリにディレクトリも含まれている場合、そのcp行は処理されません。幸い、この場合、レプリケーションは失敗し、エラーストリームにメッセージが表示されることもあります。ファイルシステムのコンテンツを上書きするのは冗談ではありません!

おすすめ記事