親ディレクトリに基づいてファイル名を変更する

親ディレクトリに基づいてファイル名を変更する

たとえば、という名前のホームディレクトリがありますmain。このホームディレクトリにはいくつかのフォルダがあり、その中にはというccc ddd名前の3つのフォルダがありますがlll、これらのフォルダだけを見つけて処理したいと思います。各サブフォルダには、3 つのサブフォルダすべてに同じ名前のフォルダがあるため、サブフォルダにはccc ddd lll同じ名前のフォルダが含まれます。

次に、その中の各サブフォルダには、thisなどのccc ddd lll特定の名前を持つ複数のファイルがあります。c_000 d_000 l_000c_001 d_001 l_001

私が最初にしたことは、次のようにファイル名の先頭に2つの親ディレクトリが追加されるようにファイル名を変更することでしたccc_foo1_c_000 ddd_foo1_d_000 lll_foo1_l_000。スクリプトでこれを行う方法を提案できる人がいるかどうか尋ねました.sh

私のホームフォルダの簡単なツリー構造は次のとおりです。

.
`-- main
    |-- ccc
    |   `-- foO1
    |   |    |-- c_000
    |   |    `-- c_001
    |   |
         -- foo2
    |       |-- c_000
    |       `-- c_001
    |   
    |   
    |-- ddd
    |   `-- foO1
    |   |    |-- d_000
    |   |    `-- d_001
    |   |
         -- foo2
    |       |-- d_000
    |       `-- d_001
    |-- lll
    |      `-- foO1
    |  |    |-- l_000
    |  |    `-- l_001
    |  |
    |   -- foo2
    |      |-- l_000
    |      `-- l_001
    |
    |-- aaa
    |-- bbb

ベストアンサー1

次のことができます。

for dir in ccc ddd lll; do 
    find "main/$dir" -type f -print0 | 
        while IFS= read -r -d '' f; do 
            dd=$(dirname "$f")
            new="${f/main\/}"
            new="${new//\//_}" 
            mv "$f" "$dd"/"$new"
        done
done

上記のスクリプトを完了すると、ファイルは次のようになります。

.
`-- main
    |-- ccc
    |   |-- fo01
    |   |   |-- ccc_fo01_c_000
    |   |   `-- ccc_fo01_c_001
    |   `-- fo02
    |       |-- ccc_fo02_c_000
    |       `-- ccc_fo02_c_001
    |-- ddd
    |   |-- fo01
    |   |   |-- ddd_fo01_d_000
    |   |   `-- ddd_fo01_d_001
    |   `-- fo02
    |       |-- ddd_fo02_d_000
    |       `-- ddd_fo02_d_001
    `-- lll
        |-- fo01
        |   |-- lll_fo01_l_000
        |   `-- lll_fo01_l_001
        `-- fo02
            |-- lll_fo02_l_000
            `-- lll_fo02_l_001

説明する

  • for dir in ccc ddd lll; do ...; done:これらの3つのディレクトリ名に対してのみこれを行い、個別に$dir
  • find "main/$dir" -type f -print0 |type f:()内のすべてのファイルを見つけて、空の文字列()で区切って印刷して、ファイル/ディレクトリ名に改行文字が含まれていても正しく機能することを確認しますmain/$dir-print0
  • while IFS= read -r -d '' f; do:これは結果を繰り返してfind各結果をとして保存します$f。バックスラッシュが特に処理されず、nullで区切られた入力を読み取ることができるようにIFS=スペースを破ることは避けてください。-r-d ''
  • dd=$(dirname "$f"): $ddNow は現在ファイルがあるディレクトリです。たとえば、main/ccc/fo01
  • new="${f/main\/}":シェルを使用しています。文字列演算main/ファイルパスから文字列を削除する機能。
  • new="${new//\//_}":上記のように、すべてを下線に置き換えます/。これにより、同様の文字列が生成されますccc_fo01_c000
  • mv "$f" "$dd"/"$new":最後に、元のファイルの$f名前を$dd/$new$dd$new

実際にこれを行う前にテストするecho前に追加することをお勧めしますmv

おすすめ記事