重複項目として宣言する前に、ファイル名とディレクトリ名に共通の文字列を含むツリー構造の名前を一括変更したり、新しい名前にコピーしたりする特別な理由から、この項目が必要であることを検討してください。これは例です(Ubuntu 14.04で試したのでGNUツールを使用しています)。
cd /tmp
mkdir myproj
mkdir -p myproj/myproj_AA/myproj_BB
touch myproj/myproj_AA/myproj_BB/myproj_CC.dat
mkdir myproj/myproj_AA/myproj_DD
touch myproj/myproj_AA/myproj_DD/myproj_EE.dat
mkdir -p myproj/myproj_XX/myproj_YY
touch myproj/myproj_XX/myproj_YY/myproj_ZZ.dat
mkdir -p myproj/myproj_XX/myproj_WW
touch myproj/myproj_XX/myproj_WW/myproj_QQ.dat
tree myproj # to visualise
ディレクトリ構造はtree
次のとおりです。
myproj
├── myproj_AA
│ ├── myproj_BB
│ │ └── myproj_CC.dat
│ └── myproj_DD
│ └── myproj_EE.dat
└── myproj_XX
├── myproj_WW
│ └── myproj_QQ.dat
└── myproj_YY
└── myproj_ZZ.dat
6 directories, 4 files
myproj/
したがって、(自分を含む)すべての項目の名前を(名前で示される場所ごとに)代わりにmyproj
変更したいと思います。したがって、まず現在のディレクトリへの相対パスを含むリストを取得する必要があります。次に、最も外側のサブディレクトリ(これは最も長い相対パス名を持つファイルと同じですがわかりません)が最初のディレクトリになるようにソートする必要があります。 (最初に/ mvディレクトリの名前を変更してからその中のファイルの名前を変更しようとすると、古いディレクトリ名を最初の引数として使用し、名前が変更されたため失敗する可能性があるためです。)myTESTproj
myproj
ls -R --group-directories-first myproj/
まず、ディレクトリを再帰的に使用してグループ化する方法を知っていますが、ls
結果は次のようになります。
$ ls -R --group-directories-first myproj/
myproj/:
myproj_AA myproj_XX
myproj/myproj_AA:
myproj_BB myproj_DD
myproj/myproj_AA/myproj_BB:
myproj_CC.dat
myproj/myproj_AA/myproj_DD:
myproj_EE.dat
myproj/myproj_XX:
myproj_WW myproj_YY
myproj/myproj_XX/myproj_WW:
myproj_QQ.dat
myproj/myproj_XX/myproj_YY:
myproj_ZZ.dat
...つまり、簡単に提供できるサブパスを含む単純なリストではありません。while read f; do ...
私が得た最も近いのは、以下を使用することですfind
。
$ find myproj/
myproj/
myproj/myproj_AA
myproj/myproj_AA/myproj_DD
myproj/myproj_AA/myproj_DD/myproj_EE.dat
myproj/myproj_AA/myproj_BB
myproj/myproj_AA/myproj_BB/myproj_CC.dat
myproj/myproj_XX
myproj/myproj_XX/myproj_YY
myproj/myproj_XX/myproj_YY/myproj_ZZ.dat
myproj/myproj_XX/myproj_WW
myproj/myproj_XX/myproj_WW/myproj_QQ.dat
これには単純なサブパスのリストがありますが、ルートノードからリーフノードまでソートされているので、まずリーフノードをソートする必要があります。似たようなことを試していますfind myproj/ | sort -n
が違いはないようです。だから私が次のようにすれば:
$ find myproj/ | sort -n | while read f; do mv -v $f $(echo $f | sed 's/myproj/myTESTproj/g'); done
‘myproj/’ -> ‘myTESTproj/’
mv: cannot stat ‘myproj/myproj_AA’: No such file or directory
mv: cannot stat ‘myproj/myproj_AA/myproj_BB’: No such file or directory
mv: cannot stat ‘myproj/myproj_AA/myproj_BB/myproj_CC.dat’: No such file or directory
...
...その後、ルートノード(ディレクトリ)の名前が最初に変更されるため、予想される再帰の名前変更はすぐに失敗するため、それに対するすべての追加参照は無効です。
では、このようなバッチの名前変更に使用するために、リーフノードを持つサブディレクトリの正しい再帰リストを最初に取得します。
ベストアンサー1
あなたの目標が名前を変更するだけであれば、ディレクトリ自体の前に各ディレクトリの内容を処理するだけでは十分ではありませんか?みんな葉(みんな目次)まず?find -depth
それがまさにそれがすることです。
$ mkdir -p a/b c/d
$ find -depth
./a/b
./a
./c/d
./c
.
find -exec
その後、Bashを使用してファイルの名前を変更できます。
$ find -depth ! -name . -name "*myproj*" -execdir bash -c '
for f; do mv "$f" "${f/myproj/myTESTproj}" ; done' bash {} +