web-dev-qa-db-ja.com

ファイル名に基づいてファイルを複数のディレクトリにソートしますか?

ファイル名に基づいてサブディレクトリに分類したい1つのディレクトリに数千のファイルがあります。それらはすべて、p- [number] _n- [number] _a- [number]。[ext]のセット構造で一貫して名前が付けられています。

ここに小さなサンプルがあります...

  • p-12345_n-987_a-1254.jpg
  • p-12345_n-987_a-9856.pdf
  • p-12345_n-987_a-926.docx
  • p-12345_n-384_a-583.pdf
  • p-12345_n-384_a-987.pdf
  • p-2089_n-2983_a-2348.gif
  • p-2089_n-1982_a-403.jpeg
  • p-38422_n-2311_a-126.pdf
  • p-38422_n-2311_a-5231.docx

私が求めているのは、次のようなフォルダ構造です。

p-12345
  ⊢ n-987
    ⊢ p-12345_n-987_a-1254.jpg
    ⊢ p-12345_n-987_a-9856.pdf
    ⊢ p-12345_n-987_a-926.docx
  ⊢ n-384
    ⊢ p-12345_n-384_a-583.pdf
    ⊢ p-12345_n-384_a-987.pdf
p-2089
  ⊢ n-2983
    ⊢ p-2089_n-2983_a-2348.gif
  ⊢ n-1982
    ⊢ p-2089_n-1982_a-403.jpeg
p-38422
  ⊢ n-2311
    ⊢ p-38422_n-2311_a-126.pdf
    ⊢ p-38422_n-2311_a-5231.docx

私はそれが理にかなっていると思います。

このようにファイルを整理するスクリプトを書くことは可能ですか?

編集:明確にするために:はい、私の質問はhowにする必要があります==ファイルを整理するスクリプトを記述できますか? :)私は、Unixとコマンドライン一般に非常に慣れていません。これまでのところ、基本的なシェルスクリプトのみを作成/使用しました。答えはおそらく正規表現が含まれるだろうという予感がありますが、それを超えてどこから始めればよいのか本当にわかりません。

私が思いついた最良のアイデアは

  1. ファイルリストをテキストファイルにエクスポートする
  2. 「_n」と「_a」を検索して「/ n」と「/ a」に置き換えます
  3. それから一連のmvコマンドを作成する
  4. シェルスクリプトとして保存します

それは必要以上にずっと長いものだと私は確信している。また、将来、より多くのファイルに対して実行する必要がある場合に備えて、繰り返し可能なものを用意したいと考えています。

3
itsViney

承知しました:

#!/bin/bash
for i in p-*_n-*.*; do
        Ppart=${i/_n-*}
        x=${i/${Ppart}_/}
        nPart=${x/_a-*}
        mkdir -p $Ppart/$nPart
        mv $i $Ppart/$nPart
done

最初に、指定したパターンに一致するすべてのファイル名をループします。各ループで、シェル置換を使用して、_n-部分から始まるファイル名の最後の部分を削除します。これにより、P部分(第1レベルのディレクトリ)が与えられます。次に、n-から_a-までのN部分が必要です。これは2つのステップで行います。最初にPpartを削除し、次に_a-パーツから始まる最後のパーツを削除します。

次に、mkdir -pを使用して、必要なディレクトリを作成します。パスがすでに存在する場合でもmkdir -pはエラーを発生させないため、コマンドの実行を決定する前にディレクトリが存在するかどうかをテストする代わりに、mkdir -pを実行する方が簡単です。

最後に、ファイルを正しいディレクトリに移動します。

4
wurtel

そして、Python(3)の別のバージョン:

import os

sourcepath='/path/to/source'
destination='/path/to/destination'

(_,_,fnames) = next(os.walk(sourcepath))
for f in fnames:
    subpath = '/'.join(f.split('_')[:-1])
    print("Moving {} to {}".format(os.path.join(sourcepath, f), os.path.join(destination, subpath , f)))
    os.makedirs(os.path.join(destination, subpath), exist_ok=True)
    os.rename(os.path.join(sourcepath, f), os.path.join(destination, subpath , f))
2
Lambert

これは最も単純なようで、仕事が完了します(私はテストしました)。私たちがしているのは、プレーンな古いsedを使用して現在の名前を変換し、適切な場所に「/」を挿入し、適切な場所にあるものを削除して、ディレクトリ名を生成することです。

for i in p*
do
    d=$(echo $i | sed -e 's|_n-|/n-|' -e 's|_a-.*||')
    mkdir -p $d
    mv -i $i $d
done
1
sitaram

素敵なワンライナーはどうですか

ls | awk -F"_" '{system("mkdir -p " $1 "/" $2 "&& mv " $0 " " $1 "/" $2 "/" $0)}'

_に基づいてファイル名セクションを分離し、必要なディレクトリを作成してから、変更されていないファイル名を新しく作成したディレクトリに移動します。

0
F. Pareto