web-dev-qa-db-ja.com

サブフォルダー内のすべてのファイル(非表示を含む)を* nixの親フォルダーに再帰的に移動する方法は?

これは少し恥ずかしい質問ですが、私のキャリアの後半でも、mvコマンドについてまだ質問があることを認めざるを得ません。

私は頻繁にこの問題を抱えています。すべてのファイルを再帰的に1レベル上に移動する必要があります。たとえば、フォルダfooがあり、その中にフォルダバーがあるとします。 Barには、ドットファイルとフォルダーを含む、ファイルとフォルダーの混乱があります。 barのすべてをfooレベルに移動するにはどうすればよいですか?

Fooが空の場合、barを1レベル上に移動し、fooを削除して、barの名前をfooに変更します。問題の一部は、「ドットを含むすべて」のmvのワイルドカードが何であるかを理解できないことです。この質問の一部はこれです-cpおよびmvコマンドがどこかで使用するワイルドカードの詳細な説明があります(これをグーグルすると、非常に基本的なチュートリアルしか表示されません)。

14
deadprogrammer

Bash(およびその他のいくつか)では、ブレース展開を使用してこれを1行で実行できます。

mv bar/{,.}* .

カンマはnullとドットを区切るため、mvコマンドは*および.*に一致するファイル名を確認します

これは、サブフォルダーからすべてのファイルを収集し、現在のディレクトリに移動します

find . -type f -exec mv -iv \{} . \;

同じ名前のファイルを書きたい場合は、

yes y | find . -type f -exec mv -iv \{} . \;
3
michelek

これを行う最も簡単な方法は、*が.whateverと一致しないため、2つのコマンドで実行することです。

cd /foo
mv bar/* ./
mv bar/.??* ./

あなたはこの間違いを犯している間に私が見つけたbar /.*を使いたくありません:

rm -rf ./.* 

これは悪いことです。誰かが理由を推測したいですか? ;-)

2
Matt Simmons

グロビングについて最初に知っておくべきことは、コマンドではなくシェルによって行われることです。詳細については、シェルのmanページを確認してください。

2
Jeff Leyser

mv .??* *は、ドットとそれに続く単一の文字以外のすべてを処理します。それが一般的な状況である場合は、.[a-zA-Z0-9]*を追加できます。それでも、.;.^.^I(タブ)などの名前のファイルは残ります。すべてを処理する必要がある場合は、もう少し複雑にする必要があります。

mv .. `ls -f | egrep -v '^.$|^..$'
1
mpez0

ディレクトリ構造_/foo/bar/_があり、barの下のすべてのファイルを1つ上のステップに移動する場合は、barディレクトリに移動して、次のように入力します。

_find . -depth -print0 | cpio --null -pvd ../
_

一般的に、私はcpio(1)がこの種のタスクに適していると思います。シェルで_info cpio_を発行して、詳細なドキュメントを確認できます。

0
fim