Wie alle Dateien aus dem aktuellen Verzeichnis in das obere Verzeichnis verschieben?

185100
Jens Erat

Wie alle Dateien aus dem aktuellen Verzeichnis in das obere Verzeichnis in Linux verschieben?

Ich habe so etwas ausprobiert mv *.*, aber es funktioniert nicht.

128
Ich habe nicht genug Repräsentanten, um die Fragen neu zu kennzeichnen, aber kann ich vorschlagen, [linux] [mv] [cwd] [files] `oder etwas Ähnliches? Stephan202 vor 14 Jahren 0
Ich habe diese Frage auf Anfrage von Stephan202 umgeändert. eleven81 vor 14 Jahren 0
http://unix.stackexchange.com/a/251091/139312 palindrom vor 8 Jahren 0

11 Antworten auf die Frage

196
Stephan202

Der Befehl, den Sie suchen, ist

mv * .[^.]* .. 

oder (siehe unten für weitere Informationen):

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

Erläuterung: Der mvBefehl verschiebt Dateien und Verzeichnisse. Das letzte Argument von mvist das Ziel (in diesem Fall das Verzeichnis eine Stufe nach oben in der Baumstruktur ..). Die Argumente davor sind die Quelldateien und Verzeichnisse. Das Sternchen ( *) ist ein Platzhalter, der alle Dateien angibt, die nicht mit einem Punkt beginnen. Dateien, die mit einem Punkt beginnen (Punktdateien), sind "versteckt". Sie werden anhand des Musters abgeglichen .[^.]*(siehe Bearbeiten unten).

Weitere Informationen finden Sie auf der von mir verlinkten Manpage mv.


Warum .[^.]*statt .*?

Wie Chris Johnsen richtig feststellt: Das Muster .*passt auch .und ... Da Sie diese nicht verschieben möchten (und können), ist es besser, ein Muster zu verwenden, das mit jedem Dateinamen übereinstimmt, der mit einem Punkt beginnt, außer diesen beiden . Das Muster .[^.]*tut genau das: Es stimmt mit jedem Dateinamen (1) überein, beginnend mit einem Punkt (2), gefolgt von einem Zeichen, das kein Punkt (3) ist, gefolgt von null oder mehr beliebigen Zeichen.

Wie Paggas ausführt, müssen wir auch das Muster hinzufügen, .??*um Dateien abzugleichen, die mit zwei Punkten beginnen. Sehen Sie seine Antwort für eine alternative Lösung mit find.

Arjans Antwort erwähnt shopt, um all diese Probleme mit dotfiles zu vermeiden. Aber es gibt immer noch Probleme mit Dateien, die mit einem Bindestrich beginnen. Und es erfordert drei Befehle. Trotzdem mag ich die Idee. Ich schlage vor, es so zu verwenden:

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

Dies wird shoptin einer Subshell ausgeführt (also kein zweiter Aufruf shopterforderlich) und wird --so verwendet, dass Dateien, die mit einem Bindestrich beginnen, nicht als Argumente interpretiert werden mv.

Die Verwendung von `. *` Kann dazu führen, dass * mv * Warnungen / Fehler ausgibt, dass `.` und` ..` nicht verschoben werden können. Sie können stattdessen `mv *. [^.] * ..` versuchen. Chris Johnsen vor 14 Jahren 7
Sehr vollständige Antwort danke. vor 14 Jahren 0
@ alain: willkommen und willkommen auf der website! (Wenn (und nur wenn) einer der hier gestellten Beiträge Ihre Frage ausreichend beantwortet hat, können Sie sie als solche kennzeichnen. Das bringt dem Poster 15 zusätzliche Reputationspunkte und zusätzlich 2 Wiederholungen.) Stephan202 vor 14 Jahren 1
Ich mag die Shopt-Lösung wirklich, die in einer Subshell läuft :) Paggas vor 14 Jahren 0
In der *. * -Syntax gibt es keinen Schaden - einschließlich .. ist nur gefährlich, wenn es mit chmod und chown und dem "recurse" -Flag verwendet wird, dh chmod -R oder chown -R. Geben Sie in solchen Fällen * niemals * chown. * Oder chmod. * Ein - wählen Sie das oberste Verzeichnis in dem Pfad, den Sie suchen, und verwenden Sie -h (folgen Sie nicht den symbolischen Links). Aber mv macht einfach nichts, also mach dir keine Sorgen. chris vor 14 Jahren 2
Dadurch können keine Verzeichnisse kopiert werden, die bereits vorhanden sind und im Ziel nicht leer sind. 'mv -f' hilft nicht. Ich glaube nicht, dass es eine Möglichkeit gibt, dies zu erzwingen, also gehe ich davon aus, dass ich zunächst die kopierten Dateien durchlaufen und sie vom Ziel aus "rm" machen muss. Wenn ich das mache, dann kann ich die Dateien nacheinander auch "mv" machen. Jonathan Hartley vor 12 Jahren 0
Gibt mv: umbenennen. [^.] * In ../.[ ^.***: Keine solche Datei oder Verzeichnis pal4life vor 9 Jahren 0
Funktioniert das. [^.] * Auf / bin / sh? jdg vor 9 Jahren 0
Was ist, wenn Sie sich im Zielverzeichnis befinden? Ich habe das verwendet und es hat funktioniert: `mv subdir / (* |. [^.] *) .`. Anmerkungen dazu? Tristan Jahier vor 9 Jahren 0
funktionierte für mich nicht "mv: kann stat '. [^.] *`: keine solche Datei oder Verzeichnis "? centos6 Exlord vor 8 Jahren 0
Die korrekten drei Muster sind `*`, `. [^.] *` Und `...? *`. Die zweite vielleicht `. [!.] *` Für ältere (POSIX) -Shells. [Lesen Sie auch] (http://stackoverflow.com/a/2910105/2350426) vor 8 Jahren 1
42
Paggas

Kurze antwort: verwenden

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

Lange Antwort:

Der Befehl

mv * .* .. 

wird nicht funktionieren, da und .*passen können . Aber der Befehl...

mv * .[^.]* .. 

wird auch nicht funktionieren, da .[^.]*zB nicht passt ..filename! Stattdessen mache ich was

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

das wird alles außer .und ... *wird alles passen, der nicht mit einem Start ., .[^.]mit einem Punkt wird außer daß alle 2 - Zeichen Dateinamen übereinstimmen .., und .??*wird mit einem Punkt mit mindestens 3 Zeichen beginnen alle Dateinamen entsprechen.

Besser noch, Sie können verwenden

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

was vermeidet die hässlichen glob hacks in mv * .[^.] .??* ..!

Ich habe auch vergessen, die Wichtigkeit von - zu beachten, damit der Befehl richtig funktioniert, wenn Dateinamen mit einem Bindestrich beginnen. Ich habe aufgenommen - in meiner Antwort aber. Eine vollständigere Antwort mit Globs ist "mv - *. [^.]. ?? * ..". Paggas vor 14 Jahren 1
+1: Ich kam zurück, um meinem Kommentar "..? *" Hinzuzufügen, und Sie hatten sich bereits darum gekümmert. Chris Johnsen vor 14 Jahren 0
Was kann daran falsch sein, mv zu versuchen ..? Es macht einfach nichts und kann nichts tun. Es gibt andere Befehle, bei denen * sie * etwas tun können (chmod und chown), aber mv und rm tun einfach nichts. oder .. chris vor 14 Jahren 1
Dies funktionierte nicht mit .git / folder; ( Daniel T. Magnusson vor 11 Jahren 0
Dies gibt mv: illegale Option - t pal4life vor 9 Jahren 1
Könntest du erklären, was die `- {} +` macht? Oder wo finde ich eine Antwort auf diese Frage? Das ist die einzige Magie, die mir in dieser Antwort bleibt. Bono vor 6 Jahren 0
Bono, die doppelten Striche sagen "mv", dass sie nach weiteren Befehlsoptionen suchen müssen. Die geschweiften Klammern sind ein resultierender Dateiname. Das Pluszeichen besagt, dass anstelle von Exec pro Ergebnis (dh pro Dateiname) so viele Ergebnisse in einem einzelnen Exec wie möglich abgelegt werden. Der Vollständigkeit halber wird mit "-t.." das Zielverzeichnis verschoben, in das alle diese Dateien verschoben werden sollen. isuldor vor 6 Jahren 1
14
Arjan

Der Vollständigkeit halber kann man auch die Bash-Shell dazu bringen, versteckte Dateien einzuschließen shopt.

shopt -s dotglob mv -- * .. shopt -u dotglob 
+1. Viel sauberer Ich denke jedoch, dass eine leichte Verbesserung in Ordnung ist. Siehe das Update zu meiner Antwort. Stephan202 vor 14 Jahren 0
8
Micky Martin

Dem MV fehlt die Funktionalität zum Verschieben versteckter Dateien bei der Verwendung. *Warum also nicht stattdessen Kopieren verwenden?

cp -rf . ..  rm -rf * 

Sie müssen sich nicht mit komplexen Lösungen des Dotglobbing und der Verwendung von Suchbefehlen befassen.

__Warning__ Wenn Sie sich im __same-Dateisystem__ bewegen, haben Sie in den meisten Fällen die Dateien nicht wirklich kopiert, sondern nur die Verzeichniseinträge aktualisiert, ohne die Inode- oder Dateieinhalte zu verschieben. Siehe auch [[1] (http://unix.stackexchange.com/a/48090/66388)]. Mit "cp" und "rm" kopieren Sie wirklich alles. Hastur vor 8 Jahren 0
6
mrucci
rsync -a --remove-source-files . .. 

rsync ist ein extrem leistungsfähiges Werkzeug zum Kopieren von Dateien, das normalerweise zur Durchführung effizienter inkrementeller Remote-Sicherungen und Spiegelungen verwendet wird.

Mit dem obigen Befehl soll rsyncder Inhalt von .in kopiert werden..

Der Schalter -aermöglicht die Rekursion in .Unterverzeichnisse und andere übliche Optionen.

Der Schalter --remove-source-filesweist rsync an, die Quelldateien nach einer erfolgreichen Kopie zu entfernen, dh, rsync verhält sich ähnlich wie der mvBefehl.

Ein wenig mehr Erklärung wäre schön. ChrisF vor 11 Jahren 1
Klar, hoffe es ist jetzt klarer. mrucci vor 11 Jahren 0
Beachten Sie, dass `--remove-source-files` keine (synchronisierten) Verzeichnisse entfernt. Dennis vor 10 Jahren 0
Eine nette, akzeptierte Lösung gibt mir den Fehler `-bash: / bin / mv: Argumentliste zu lang`. Dieses wirkt wie der Charme. userlond vor 7 Jahren 0
2
DaveParillo

Letztendlich mv .schlägt der Versuch fehl, weil mv das Verzeichnis, in dem Sie sich gerade befinden, nicht mv * ..auflösen kann. Sie können die Dateien in der cwd verschieben.

2
DigitalRoss
mv * .??* ../. 

*Ruft alle Nicht-Punkt-Dateien ab. .??*bekommt alles. Dateien mindestens drei Bytes lang, was für alle legitimen geeignet ist. Alles, was links Sie wahrscheinlich zu wollen, rmanstatt mvsowieso.

Das ../.bietet keine direkten Vorteile gegenüber, ..aber wenn Sie in ein Verzeichnis wechseln, ist es eine sehr gute Angewohnheit, darauf zuzugreifen, da es nach Belieben fehlschlägt, wenn der Pfad fehlerhaft ist. Wenn Sie beispielsweise denkenmv xyz bletch, dass bletch es sich um ein Verzeichnis handelt, können Sie mit mv xyz bletch/..

Sie könnten `. [^.]` Hinzufügen, um Cover-Dateien wie `.a` zu erhalten. Chris Johnsen vor 14 Jahren 2
Es gibt keinen Unterschied zwischen ../ und ../. also würde ich mir nicht die Mühe machen, das einzugeben. nach dem Schrägstrich. Im Fall von mv und rm schadet es auch nicht. und .. in der Liste, dh mit mv *. * / path / to / file / ist nichts Unheimliches oder Falsches, genauso wie rm. oder sogar -rf. tut nichts chris vor 14 Jahren 0
2
Barry

Dieser minimierte Befehl funktioniert auf den meisten modernen Shells:

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

Ansonsten wird eine tragbare Lösung erwähnt:

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

Eigenschaften:

  1. \ verhindert, dass Aliase unerwünscht geändert werden.

  2. - verhindert, dass Dateinamen mit führenden Bindestrichen (-xyz) als Befehlszeilenargumente interpretiert werden.

  3. . [^.] entspricht allen zwei Zeichendateinamen, die mit beginnen. außer ..

  4. . ?? * entspricht allen anderen Dateinamen drei Zeichen oder länger.

Naive Implementierungen:

  1. Im Folgenden werden ausgeblendete UNIX-Dateinamen, die mit beginnen, übersprungen. (.bashrc).

    mv * .. 
  2. Die folgenden Übereinstimmungen entsprechen .., die rekursiv versucht, jedes Verzeichnis schließlich zurück nach / in .. des aktuellen Arbeitsverzeichnisses ($ PWD oder pwd) zu verschieben. Benutze niemals.

    mv .* .. 
2
jrw32982

Es ist mehr richtig um das Muster zu verwenden, * .[!.] .??*als * .[^.] .??*da erstere auch mit älteren Shells wie ksh88 arbeiten:

mv -- * .[!.] .??* .. 
  • -- verhindert Probleme, wenn Sie einen Dateinamen haben, der mit beginnt -
  • * Stimmt mit allen Dateinamen überein, die nicht mit a beginnen .
  • Es gibt keine Dateinamen mit einem Zeichen, die mit einem beginnen, .den Sie verschieben können / sollen
  • .[!.] stimmt mit allen zwei Zeichendateinamen überein, die mit a beginnen .
  • .??* stimmt mit allen drei Zeichennamen (oder mehr) überein, die mit a beginnen .

Bei ksh88 stimmt das Dateinamensmuster .[^.]tatsächlich mit den Dateinamen überein ..(die immer vorhanden sind) und .^(die wahrscheinlich nicht existieren) und hat einen gegenteiligen Effekt gegenüber dem Gewünschten.

0
user3192145

Finden und grep arbeiten auch. Diese Art von Struktur kann hilfreich sein, wenn Sie Dateien anhand komplexerer Kriterien auswählen möchten, indem Sie find und egrep ändern.

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