web-dev-qa-db-ja.com

すべてのファイルを現在のディレクトリから上位ディレクトリに移動する方法

Linuxで現在のディレクトリから上位ディレクトリにすべてのファイルを移動する方法

mv *.*のようなものを試しましたが、うまくいきません。

132
asksuperuser

あなたが探しているコマンドは

mv * .[^.]* ..

または(詳細は下記を参照)

(shopt -s dotglob; mv -- * ..)

説明: mv コマンドは、ファイルとディレクトリーを移動します。 mvの最後の引数がターゲットです(この場合、ディレクトリはツリーの1つ上のディレクトリ、..)です。その前の引数はソースファイルとディレクトリです。アスタリスク(*)は、ドットで始まらないすべてのファイルに一致するワイルドカードです。ドットで始まるファイル(dotfiles)は「隠されています」。それらはパターン.[^.]*を使ってマッチングされます(下記の編集を見てください)。

mvの詳細については、リンクしたマンページを参照してください。


なぜ.[^.]*ではなく.*なのでしょうか。

Chris Johnsen は正しく指摘しています。パターン.*.および..と一致します。これらを移動したくない(できない)ので、ドットで始まるファイル名に一致するパターンを使用することをお勧めします。これらの2つは除きます。パターン.[^.]*はちょうどそれをします:それは、ドット(2)とそれに続く文字ではなくドット(3)とそれに続く0個以上の任意の文字で始まるファイル名(1)に一致します。 。

Paggasが指摘しているように 、パターンも追加する必要があります。 2つのドットで始まるファイルを照合するための.??*find を使った別の解決策については彼の答えを見てください。

ドットファイルに関するこれらの問題をすべて回避するために、Arjanの 回答shopt に言及しています。しかし、それでもダッシュで始まるファイルにはまだ問題があります。そしてそれは3つのコマンドを必要とします。それでも、私はそのアイデアが好きです。私はこのように使うことを提案します:

(shopt -s dotglob; mv -- * ..)

これは、サブシェルでshoptを実行し(したがって、shoptへの2回目の呼び出しは不要)、ダッシュで始まるファイルがmvの引数として解釈されないように--を使用します。

199
Stephan202

短い答え:使用

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

長い答え:

コマンド

mv * .* ..

.*.および..と一致する可能性があるため、機能しません。しかし、コマンド

mv * .[^.]* ..

.[^.]*は一致しないので、..filename!のようにも機能しません。代わりに、私がしているのは

mv * .[^.] .??* ..

これは...以外のすべてにマッチします。 *は、.で始まらないものすべてに一致し、.[^.]は、..を除く、ドットで始まる2文字すべてのファイル名と一致し、.??*は、3文字以上のドットで始まるすべてのファイル名と一致します。

いっそのこと、あなたが使用することができます

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

これはmv * .[^.] .??* ..の醜いglobハックを避けます!

42
Paggas

完全を期すために、 shopt を使用して、隠しファイルを含めるようBashシェルに指示することもできます。

shopt -s dotglob
mv -- * ..
shopt -u dotglob
14
Arjan

Mvは*を使うとき隠しファイルを移動する機能を欠いています - それでは代わりにコピーを使わないのはなぜ?

cp -rf . ..

rm -rf *

Dotglobbingやfindコマンドの使用に関する複雑な解決策を学ぶ必要はありません。

8
Micky Martin
rsync -a --remove-source-files . ..

rsync は非常に強力なファイルコピーツールで、一般に効率的な増分リモートバックアップおよびミラーリングを実行するために使用されます。

上記のコマンドで、rsync.の内容を..にコピーするように伝えています。

スイッチ-a.サブディレクトリへの再帰を可能にし、他のいくつかの共通オプションを可能にします。

スイッチ--remove-source-filesは、正常にコピーされた後にソースファイルを削除するようにrsyncに指示します。つまり、rsyncをmvコマンドと同様に動作させます。

6
mrucci

前者はksh88などの古いシェルでも動作するので、* .[!.] .??*より* .[^.] .??*というパターンを使用するほうが正しいです。

mv -- * .[!.] .??* ..
  • --で始まるファイル名がある場合、-は問題を防ぎます
  • *は、.で始まらないすべてのファイル名と一致します。
  • 移動できる.で始まる1文字のファイル名はありません
  • .[!.]は、.で始まる2文字すべてのファイル名と一致します。
  • .??*は、.で始まる3文字(またはそれ以上)のすべてのファイル名と一致します。

Ksh88では、ファイル名パターン.[^.]は、実際にはファイル名..(常に存在する)および.^(おそらく存在しない)と一致するため、望みの結果とは逆の効果があります。

2
jrw32982

この最小化されたコマンドは、最近のほとんどのシェルで機能します。

\mv -- {,.{[^.],??}}* ..

他に言及されているのは移植性のある解決策です:

\mv -- * .[^.] .??* ..

特徴:

  1. エイリアスが不必要にmvを変更するのを防ぎます。

  2. - 先頭のハイフン(-xyz)を含むファイル名がコマンドライン引数として解釈されないようにします。

  3. 。[^。]は、で始まる2文字のファイル名すべてに一致します。 ..以外.

  4. 。?? *は、3文字以上の他のすべてのファイル名と一致します。

単純実装:

  1. 次の例では、隠れているUNIXのファイル名(で始まるもの)はスキップされます。 (.bashrc).

    mv * ..
    
  2. 以下は、すべてのディレクトリを最終的に現在の作業ディレクトリ($ PWDまたはpwd)の/に移動することを再帰的に試みます。 絶対に使わないでください

    mv .* ..
    
2
dhchdhd

Mvは現在いるディレクトリのリンクを解除できないため、最終的にmv .を試すのは失敗します。mv * ..を使用してcwd内のファイルを移動することもできます。

2
DaveParillo
mv * .??* ../.

*はすべてのドットではないファイルを取得します。 .??*はすべて取得します。少なくとも3バイトの長さのファイル。これはすべての合法的なファイルに対して機能します。とにかくrmではなくmvを使いたいと思うかもしれません。

../...を超える直接的な利点を提供しませんが、ディレクトリに移動するときに入るのは非常に良い習慣です。パスに問題がある場合は失敗するためです。たとえば、thinkbletchがディレクトリであるmv xyz bletchは、mv xyz bletch/.でより確実にすることができます。

2
DigitalRoss

仕事も見つけてgrepしましょう。このような構造は、findおよびegrepを変更してより複雑な基準でファイルを選択したい場合に役立ちます。

find -maxdepth 1 | egrep '^./.'         # Returns all files

mv `find -maxdepth 1 | egrep '^./.'` .. # mv <all files> ..
0
user3192145

私はすべてのファイルをその親ディレクトリに移動するための最も簡単な解決策だと思います。だろう

mv "`ls`" ../

隠しファイル/ディレクトリがある場合

つかいます:

mv "`ls -a`" ../ 2>/dev/null

また、あるフォルダの内容をその内部フォルダの1つに移動したいとしましょう(たとえば)。

つかいます:

mv "`ls -a`" /tony 2>/dev/null

注:

"`ls -a`" 

スペースを含むファイルを移動します。

2>/dev/null

ls -a.および..フォルダーも印刷し、それらを移動またはコピーすることはできないため、警告/エラーを抑制するためです。そのため、それらのフォルダでは移動できないというエラーが表示され(2>/dev/nullを使用しない場合)、残りの部分は非常に快適に移動されます。

隠しファイルがない場合はls -aを避け、lsを使用するのが最善です。

0