私はこのフォルダー構造を持っています:
├── foo1
│ ├── bar1.txt
│ └── bar2.txt
├── foo2
│ ├── bar3.txt
│ └── bar4 with a space.txt
└── foo3
└── qux1
├── bar5.txt
└── bar6.txt
各フォルダーレベルの間にアンダースコアを付けて、これにフラット化したいと思います。
├── foo1_bar1.txt
├── foo1_bar2.txt
├── foo2_bar3.txt
├── foo2_bar4 with a space.txt
├── foo3_qux1.bar6.txt
└── foo3_qux1_bar5.txt
調べてみましたが、うまくいく解決策が見つかりませんでした。ほとんどの場合、私の問題には2つの特殊性があるためだと思います。ルートレベル内に複数のフォルダーレベルがある場合と、一部のファイルにスペースがある場合があります。
これをbashで達成する方法はありますか?ありがとう!
編集:グリーンジャックマンを実行すると、答えが得られます。
第1レベルのフォルダーには2つの下線があります。これを回避する方法、または名前を1つだけアンダースコアに変更する方法はありますか?ありがとう。
find */ -type f -exec bash -c 'file=${1#./}; echo mv "$file" "${file//\//_}"' _ '{}' \;
正常に機能している場合はecho
を削除します。エコーされたコマンドが引用符を表示しないことを心配しないでください。スクリプトはスペースを含むファイルを適切に処理します。
空になったサブディレクトリを削除する場合:
find */ -depth -type d -exec echo rmdir '{}' \;
Perlの名前変更を使用する:
find . -depth -type f -exec rename 's@(?<!\.)/@_@g' -- {} \;
$ find -type f
./foo2_bar4 whit a space.txt
./foo3_qux1_bar6.txt
./foo2_bar3.txt
./foo3_qux1_bar5.txt
./foo1_bar2.txt
./foo1_bar1.txt
(?<!\.)
を使用して、最初の./
に触れないようにします私は空のディレクトリを保持します。お気軽に:
find . -depth -type d -exec rm {} \;
これを実行できる場合とできない場合がある同じ名前のツールが他にもあるため、注意してください。
次のコマンドを実行すると(GNU
)
$ file "$(readlink -f "$(type -p rename)")"
そしてあなたは次のような結果を持っています
.../rename: Perl script, ASCII text executable
含まない:
ELF
次に、これは適切なツールのようです=)
そうでない場合は、Debian
およびUbuntu
のような派生物のデフォルト(通常は既にそうです)にするには、次のようにします。
$ Sudo update-alternatives --set rename /path/to/rename
(/path/to/rename
をPerl's rename
コマンドのパスに置き換えます。
このコマンドがない場合は、パッケージマネージャーを検索してインストールするか、 手動で実行してください
最後に重要なことですが、このツールはもともとPerlの父親であるLarry Wallによって書かれました。
pax
...
pax -Xrwls '|/|_|g' */ "$PWD"
これにより、現在のディレクトリに、_
が/
に置き換えられた子ディレクトリ内のすべてのファイルへのハードリンクが作成されます。次に、結果を調べて、すべての子ディレクトリを削除できます...
rm -rf */
...結果が好みに合っていることを確認したら、.
以下のコマンドで試すことができます。
$ find -type f -exec bash -c 'mv $0 $(echo $0|sed "s/\//_/2")' {} \;
上記のコマンドはファイルを移動し、ディレクトリは残りますが、後で削除できます。
$ ls
foo1_bar1.txt foo1_bar2.txt foo2_bar3.txt foo2_bar4.txt foo3_bar5.txt foo3_bar6.txt