web-dev-qa-db-ja.com

ディレクトリ名とそのディレクトリ内のファイル名のWordを置き換えます

私はこのようなディレクトリ構造を持っています:

Bookname Edition 1
  Bookname Edition 1 type1.pdf
  Bookname Edition 1 type2.pdf
Bookname Edition 2
  Bookname Edition 2 type1.pdf
  Bookname Edition 2 type2.pdf

ディレクトリの名前をEditionからVolumeに再帰的に変更しますおよびこれらのディレクトリのファイル名。

私はこれから始めました、そしてディレクトリにいるならそれは問題ありません:

for f in *.pdf; do
    a="$(echo $f | sed s/Edition/Volume/)"
    mv "$f" "$a"
done

次に、これをディレクトリの下のすべてのファイルを変更しようとしましたが、それが私が立ち往生したときです...

これを行う方法を教えてください、またはこれを行うより良い方法を教えてください。 100個のディレクトリに15000個のPDFがあります。

7
Bishop

構造に2つのレベルしかない場合、再帰を使用する必要はありません。

sedを使用してファイル名を解析しないでください。正規表現とsedスタイルの構文を使用してファイルの名前を変更する場合は、renameを使用します。 Ubuntu 17.10を使用している場合は、インストールする必要があります

Sudo apt install rename

次に、 pa4080's answer を使用できます。

renameで、テストには-nオプションを使用します。

rename -n 'expression' file(s)

mvコマンドを使用することもできます。 1行のコマンドとして:

for d in ./*/; do mv -v "$d" "${d/Edition/Volume}"; done; for f in ./*/*; do mv -v "$f" "${f/Edition/Volume}"; done

echoを使用したテストにはmv、つまりecho mv -v source destを使用できますが、ループを個別にテストして実行しない限り、ここでは不正確な結果が得られます。

スクリプトとして:

#!/bin/bash

# rename directories first
for d in ./*/; do
    mv -v "$d" "${d/Edition/Volume}"
done

# now rename files
for f in ./*/*; do
    mv -v "$f" "${f/Edition/Volume}"
done

mvおよびrenameは、--を認識して、オプションの終わりを示します。この例ではすべてのパスが./で始まるため、これを使用する必要はありませんが、パスが-で始まる場合は、オプションの最後に--を使用します(例:rename -n -- 's/foo/bar/' *、これらのパスがオプションとして解釈されるのを防ぎます。

11
Zanna

このタスクを実行するには、コマンドrenameを2回使用できます。

rename 's/Edition/Volume/' */        # rename the directories
rename 's/Edition/Volume/' */*.pdf   # rename the PDF files inside

同様の質問が2つあります。

6
pa4080

マルチレベルのディレクトリでは、ワンステップで実行できますが、問題はディレクトリの名前を下から上に変更し、内容が変更される前にコマンドまたはスクリプトがディレクトリ名を変更しないようにする必要があることです。

Pythonでは、次を使用できます。

os.walk

と組み合わせて

topdown=False

スクリプト内:

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

for root, dirs, files in os.walk(sys.argv[1], topdown=False):
    for f in files:
        shutil.move(
            root+"/"+f, root+"/"+f.replace("Edition", "Volume").strip()
        )
    for dr in dirs:
        shutil.move(
            root+"/"+dr, root+"/"+dr.replace("Edition", "Volume").strip()
        )

スクリプトをchange_name.pyとして保存し、ディレクトリを引数として実行します。

python3 /path/to/change_name.py <directory>

これは、任意の数のレベルで再帰的に機能します。

5
Jacob Vlijm

findと組み合わせた-depthオプションでprenameを使用します。

find [DIRS...] -depth | prename -n 's|Edition(?=[^/]*$)|Volume|'

説明:

  • -depthは、親の前にディレクトリの子を選択します。選択したパス名を名前変更のために「消費」するツールは、親の前に子の名前を変更できます。

  • s|Edition(?=[^/]*$)|Volume|は、パス名で最初に出現するEditionVolumeで置き換えますが、残りがそうでない場合のみ tが/を含む、i。 e。最後のパス名コンポーネント(肯定的な先読み(?=[^/]*$)によって達成される)にのみ適用されます。

  • -nは、prenameに、実際にパスの名前を変更するのではなく、パスの名前を変更する方法を出力するように指示します。 実際に名前を変更するには、このオプションを削除します。

1
David Foerster