フォルダ構造は次のようになります:
├── 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 で実現する方法をご存知ですか? ありがとうございます!
編集: gleen jackman の提案した回答を実行すると、次のようになります:
最初のレベルのフォルダーには 2 つのアンダースコアがあります。これを回避する方法、またはアンダースコアが 1 つだけになるように名前を変更する方法をご存知ですか? ありがとうございます。
答え1
find */ -type f -exec bash -c 'file=${1#./}; echo mv "$file" "${file//\//_}"' _ '{}' \;
echo
動作に問題がなければ削除してください。エコーされたコマンドに引用符が表示されなくても心配する必要はありません。スクリプトはスペースを含むファイルを適切に処理します。
空になったサブディレクトリを削除する場合:
find */ -depth -type d -exec echo rmdir '{}' \;
答え2
perl の rename を使用する:
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 によって作成されました。
答え3
とpax
...
pax -Xrwls '|/|_|g' */ "$PWD"
_
これにより、が に置き換えられた、現在のディレクトリの子ディレクトリ内のすべてのファイルへのハードリンクが作成されます/
。その後、結果を調べて、すべての子ディレクトリを削除できます...
rm -rf */
...結果が満足のいくものであることを確認したら。
答え4
以下のコマンドを試すことができます。
$ 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