it-swarm.com.de

Wie verschiebe ich alle Dateien aus dem aktuellen Verzeichnis in das übergeordnete Verzeichnis?

Wie verschiebe ich alle Dateien vom aktuellen Verzeichnis in das übergeordnete Verzeichnis unter Linux?

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

131
asksuperuser

Der gesuchte Befehl lautet

mv * .[^.]* ..

oder (siehe unten für weitere Informationen):

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

Erläuterung: Der Befehl mv verschiebt Dateien und Verzeichnisse. Das letzte Argument für mv ist das Ziel (in diesem Fall das Verzeichnis, das einen Schritt nach oben im Baum steht, ..). Die Argumente davor sind die Quelldateien und -verzeichnisse. Das Sternchen (*) ist ein Platzhalter, der allen Dateien entspricht, die nicht mit einem Punkt beginnen. Dateien, die mit einem Punkt beginnen (Punktdateien), werden "ausgeblendet". Sie werden anhand des Musters .[^.]* abgeglichen (siehe Bearbeitung unten).

Weitere Informationen zu mv finden Sie in der von mir verlinkten Manpage.


Warum .[^.]* statt .*?

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

Wie Paggashervorhebt , müssten wir auch das Muster .??* hinzufügen, um Dateien abzugleichen, die mit zwei Punkten beginnen. Siehe seine Antwort für eine alternative Lösung mit find .

Arjans Antwort erwähnt shopt , um all diese Probleme mit Punktdateien zu vermeiden. Aber dann gibt es immer noch das Problem mit Dateien, die mit einem Bindestrich beginnen. Und es erfordert drei Befehle. Trotzdem gefällt mir die Idee. Ich schlage vor, es so zu benutzen:

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

Dies führt shopt in einer Subshell aus (daher ist kein zweiter Aufruf von shopt erforderlich) und verwendet --, sodass Dateien, die mit einem Bindestrich beginnen, nicht als Argumente für mv interpretiert werden.

199
Stephan202

Kurze Antwort: verwenden

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

Lange Antwort:

Der Befehl

mv * .* ..

funktioniert nicht, da .* mit . und .. übereinstimmen kann. Aber der Befehl

mv * .[^.]* ..

funktioniert auch nicht, da .[^.]* nicht übereinstimmt, z. B. ..filename! Stattdessen mache ich

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

das passt zu allem außer . und ... * stimmt mit allem überein, was nicht mit einem . beginnt, .[^.] stimmt mit allen 2-stelligen Dateinamen überein, die mit einem Punkt beginnen, mit Ausnahme von .., und .??* stimmt mit allen Dateinamen überein, die mit einem Punkt mit mindestens 3 Zeichen beginnen.

Besser noch, du kannst verwenden

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

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

42
Paggas

Der Vollständigkeit halber kann man die Bash Shell auch anweisen, versteckte Dateien einzuschließen, indem man shopt verwendet:

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

Dem mv fehlt die Funktionalität, versteckte Dateien zu verschieben, wenn * verwendet wird. Warum also nicht stattdessen copy verwenden?

cp -rf . ..

rm -rf *

Keine Notwendigkeit, sich mit komplexen Lösungen für das Aufsplittern und Verwenden von Suchbefehlen zu befassen.

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

rsync ist ein äußerst leistungsfähiges Tool zum Kopieren von Dateien, das im Allgemeinen zum Ausführen effizienter inkrementeller Remote-Sicherungen und -Spiegelungen verwendet wird.

Mit dem obigen Befehl weisen wir rsync an, den Inhalt von . in .. zu kopieren.

Der Schalter -a aktiviert die Rekursion in .-Unterverzeichnisse und aktiviert einige andere allgemeine Optionen.

Der Schalter --remove-source-files weist rsync an, die Quelldateien nach einer erfolgreichen Kopie zu entfernen, d. H. Rsync verhält sich ähnlich wie der Befehl mv.

6
mrucci

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

mv -- * .[!.] .??* ..
  • -- verhindert Probleme, wenn Sie einen Dateinamen haben, der mit - beginnt
  • * stimmt mit allen Dateinamen überein, die nicht mit einem . beginnen
  • es gibt keine Dateinamen mit einem einzigen Zeichen, die mit einem . beginnen, den Sie verschieben können/sollten
  • .[!.] stimmt mit allen Dateinamen mit zwei Zeichen überein, die mit einem . beginnen
  • .??* stimmt mit allen dreistelligen Dateinamen (oder längeren) überein, die mit einem . beginnen.

Bei ksh88 stimmt das Dateinamenmuster .[^.] tatsächlich mit den Dateinamen .. (die immer vorhanden sind) und .^ (die wahrscheinlich nicht vorhanden sind) überein und hat eine entgegengesetzte Wirkung wie gewünscht.

2
jrw32982

Dieser minimierte Befehl funktioniert auf den meisten modernen Shells:

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

Ansonsten wird eine portable Lösung genannt:

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

Eigenschaften:

  1. \ verhindert, dass Aliase sich unerwünscht verändern.

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

  3. . [^.] stimmt mit allen zwei Zeichendateinamen überein, die mit. außer ..

  4. . ?? * stimmt mit allen anderen Dateinamen überein, die mindestens drei Zeichen lang sind.

Naive Implementierungen:

  1. Bei den folgenden Schritten werden versteckte UNIX-Dateinamen übersprungen, die mit "" beginnen. (.bashrc).

    mv * ..
    
  2. Die folgenden Übereinstimmungen .., die rekursiv versuchen, jedes Verzeichnis irgendwann ganz nach/in .. des aktuellen Arbeitsverzeichnisses ($ PWD oder pwd) zu verschieben. Benutze niemals.

    mv .* ..
    
2
dhchdhd

Letztendlich schlägt der Versuch von mv . fehl, da mv die Verknüpfung des Verzeichnisses, in dem Sie sich gerade befinden, nicht aufheben kann. Sie können mv * .. verwenden, um die Dateien im CWD zu verschieben.

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

* ruft alle Nicht-Punkt-Dateien ab. .??* bekommt alles. Mindestens drei Bytes lange Dateien, die für alle legitimen funktionieren. Alles, was übrig bleibt, möchten Sie wahrscheinlich rm anstatt mv.

Der ../. bietet keine direkten Vorteile gegenüber dem .., aber es ist eine sehr gute Angewohnheit, in ein Verzeichnis zu wechseln, da er nach Belieben fehlschlägt, wenn etwas mit dem Pfad nicht stimmt. Zum Beispiel kann mv xyz bletch, bei dem Sie denken bletch ein Verzeichnis ist, mit mv xyz bletch/. sicherer gemacht werden.

2
DigitalRoss

Finden und arbeiten auch. Diese Art von Struktur kann hilfreich sein, wenn Sie Dateien nach komplexeren 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> ..
0
user3192145

Ich denke, die einfachste Lösung für das Verschieben aller Dateien in das übergeordnete Verzeichnis. wäre

mv "`ls`" ../

oder, Wenn versteckte Dateien/Verzeichnisse vorhanden sind

benutzen:

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

Nehmen wir an, Sie möchten den Inhalt eines Ordners in einen der internen Ordner verschieben (z. B.).

benutzen:

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

Hinweis:

"`ls -a`" 

Verschieben der Dateien mit Leerzeichen.

2>/dev/null

Dient zum Unterdrücken der Warnung/des Fehlers, da ls -a auch den Ordner . und .. druckt und Sie diese nicht verschieben oder kopieren können. Für diese Ordner wird der Fehler angezeigt (wenn wir nicht 2>/dev/null verwenden), dass sie nicht verschoben werden können, und der Rest wird ganz bequem verschoben.

Vermeiden Sie am besten ls -a, wenn keine versteckten Dateien vorhanden sind, und verwenden Sie einfach ls.

0