テスト環境:
- ~ からディレクトリを作成し、 ~
0
から ~ までの9
ファイルで埋めます。a
z
$ mkdir {0..9} && touch {0..9}/{a..z}
- 結果
find
:$ find -type f ./0/a ./0/b ... ./9/y ./9/z
出力を次のように変換するにはどうすればよいですか?
./0a
./0b
...
./9y
./9z
答え1
Perlを使用したスタンドアロンコマンドrename
:
rename -n 's|/||' */*
すべてが正常な場合は、-n
残りの空のディレクトリを削除してから削除します。
rmdir {0..9}
答え2
POSIXツールを使うと
find . -type f -exec sh -c 'for f; do dirn="${f%/*}"; mv -- "$f" "$dirn${f##*/}"; done' sh {} +
find
シェルを呼び出し、各ファイルに対して for ループを実行します。
dirn="${f%/*}"
ファイル名から最後のスラッシュの後のすべての項目を除く、含めて親ディレクトリ名を取得します。${f##*/}
ファイル名から最後のスラッシュの前のすべての項目を除いて(含む)パスなしでファイル名を取得します。
これら2つのシェル構造の機能は次のとおりです。dirname
そしてbasename
したがって、このコマンドの同等の形式は次のとおりです。
find . -type f -exec sh -c 'for f; do mv -- "$f" "$(dirname "$f")$(basename "$f")"; done' sh {} +
、各ファイルに対して2つの追加プロセスを作成する必要があるため、遅くする必要があります。
複数のディレクトリに移動する必要がない場合(例に示すように)、単純なシェルループを使用して移動できます。
for f in */*; do dirn="${f%/*}"; echo mv -- "$f" "$dirn${f##*/}"; done