So verschieben Sie alle Dateien einschließlich versteckter Dateien über * in das übergeordnete Verzeichnis

113

Es muss eine beliebte Frage sein, aber ich konnte keine Antwort finden.

So verschieben Sie alle Dateien über *, einschließlich versteckter Dateien, in das übergeordnete Verzeichnis wie folgt:

mv /path/subfolder/* /path/

Dadurch werden alle Dateien wie erwartet in das übergeordnete Verzeichnis verschoben, versteckte Dateien werden jedoch nicht verschoben. Wie geht das?

TroodoN-Mike
quelle
1
Diese Frage hat ein Duplikat bei SU , mit einer noch korrekteren Antwort (allerdings nicht die akzeptierte): cp -r /path/to/source/. /destination
Florian

Antworten:

202

Eine umfassende Reihe von Lösungen hierzu finden Sie in der Antwort von UNIX & Linux auf Wie verschieben Sie alle Dateien (einschließlich versteckter Dateien) von einem Verzeichnis in ein anderes? . Es zeigt Lösungen in Bash, zsh, ksh93, Standard (POSIX) sh usw.


Sie können diese beiden Befehle zusammen verwenden:

mv /path/subfolder/* /path/   # your current approach
mv /path/subfolder/.* /path/  # this one for hidden files

Oder alle zusammen ( danke pfnuesel ):

mv /path/subfolder/{.,}* /path/

Welches erweitert sich zu:

mv /path/subfolder/* /path/subfolder/.* /path/

(Beispiel: echo a{.,}berweitert auf a.b ab)

Beachten Sie, dass hier einige Warnungen angezeigt werden:

mv: cannot move ‘/path/subfolder/.’ to /path/.’: Device or resource busy
mv: cannot remove /path/subfolder/..’: Is a directory

Sich einfach ignorieren: dies geschieht , weil /path/subfolder/{.,}*auch erweitert zu /path/subfolder/.und /path/subfolder/.., die das Verzeichnis und das übergeordnete Verzeichnis (siehe Was tun und „..“ bedeuten , wenn sie in einem Ordner „“? ).


Wenn Sie nur kopieren möchten, können Sie nur Folgendes verwenden:

cp -r /path/subfolder/. /path/
#                     ^
#                     note the dot!

Dadurch werden alle normalen und versteckten Dateien kopiert, da sie /path/subfolder/.auf "Alles aus diesem Verzeichnis" erweitert werden (Quelle: Wie kopiere ich mit cp, um versteckte Dateien und versteckte Verzeichnisse sowie deren Inhalt einzuschließen? )

fedorqui 'SO hör auf zu schaden'
quelle
2
Die geschweiften Klammern sind nur eine Abkürzung für mv /path/subfolder/* /path/subfolder/.* /path/, nicht unbedingt erforderlich, um die beiden Befehle zu einem zu kombinieren.
Chepner
7
Ich erhalte die folgende Fehlermeldung:mv: overwrite `/path/.'? y mv: cannot move `/path/subfolder/.' to `/path/.': Device or resource busy mv: overwrite `/path/..'? y mv: cannot move `/path/subfolder/..' to `/path/..': Device or resource busy
Dejan
@Dejan Ignoriere es einfach. .bezeichnet das aktuelle Verzeichnis und ..bezeichnet das upVerzeichnis. Sie müssen bemerkt haben, dass alle anderen Dateien verschoben werden.
Debiprasad
Erwähnenswert ist, dass die Verknüpfung der Klammern nicht für alle Shells funktioniert, aber ich denke, der Befehl @chepner wird es tun
Jesús Carrera
7
"Ignoriere einfach die Warnung" ist möglicherweise nicht immer eine gute Idee. Im Moment habe ich ein Problem mit einem Skript, bei dem ich die Ausführung stoppen muss, wenn ein Schritt fehlschlägt. Da diese Lösung immer einen Fehler verursacht, wird mein Skript beendet. Ich brauche einen Weg, um festzustellen, ob der Befehl mv fehlgeschlagen ist oder nicht ...
MarioVilas
29

Ich denke, das ist das eleganteste, da es auch nicht versucht, sich zu bewegen ..:

mv /source/path/{.[!.],}* /destination/path
Vanderstaaij
quelle
1
Ja, ich habe bemerkt, dass es auch diese Fehlermeldungen gibt, nette Entdeckung.
Joseph Astrahan
Ich denke, das ist eine sehr gute Lösung, aber es ist schwer, sich an dieses Muster zu erinnern
Dylan B
Dies würde Dateien wie ..anythingoder ...anythingusw. vermissen . - stackoverflow.com/a/31438355/2351568 enthält den richtigen regulären Ausdruck für dieses Problem. || aber trotzdem shopt -s dotglobist die Verwendung immer noch die bessere Lösung!
DJCrashdummy
@ DylanB merke es dir nicht. Denken Sie daran, dass es mit dem übereinstimmt, was in den geschweiften Klammern steht, getrennt durch Kommas. {a,b}*würde alle Dateien finden, die mit a oder b beginnen, wie "Anatomie" und "Bulldozer". Die zweite Übereinstimmung ist nur eine leere Übereinstimmung, die entspricht *, und die erste Übereinstimmung entspricht .[!.], wobei die Gruppe [!.]eine Gruppe bedeutet, die NICHT mit a beginnt .. Das heißt .*aber nicht ..*.
Mazunki
28

Dadurch werden alle Dateien wie erwartet in das übergeordnete Verzeichnis verschoben, versteckte Dateien werden jedoch nicht verschoben. Wie geht das?

Sie könnten einschalten dotglob:

shopt -s dotglob               # This would cause mv below to match hidden files
mv /path/subfolder/* /path/

Zum Ausschalten dotglobmüssen Sie sagen:

shopt -u dotglob
devnull
quelle
Sehr hilfreich. Wollte mehr herausfinden, aber shopt ist ein eingebautes Gerät, man shoptfunktioniert also nicht und help shoptist sehr kurz. Aber Sie können es tun bashman () { man bash | less -p "^ $1 "; }und dann bashman shoptalles direkt lesen. (Möglicherweise muss n gedrückt werden, um zum Befehl zu springen, wenn Zeilen mit shopt beginnen, wie ich festgestellt habe.)
Nick Rice
2
Dies ls
wirkt
5

Alternative einfachere Lösung ist die Verwendung von rsyncDienstprogramm:

sudo rsync -vuar --delete-after --dry-run path/subfolder/ path/

Hinweis: Der obige Befehl zeigt an, was geändert werden soll. Entfernen Sie, um die tatsächlichen Änderungen auszuführen--dry-run .

Der Vorteil ist, dass der ursprüngliche Ordner ( subfolder) ebenso wie ein Teil des Befehls entfernt wird. Wenn mvSie hier Beispiele verwenden, müssen Sie Ihre Ordner noch bereinigen, ganz zu schweigen von zusätzlichen Kopfschmerzen, um versteckte und nicht versteckte Dateien in einem einzigen zu behandeln Muster.

Darüber hinaus wird rsyncdas Kopieren / Verschieben von Dateien zwischen Fernbedienungen unterstützt, und es wird sichergestellt, dass Dateien genau so kopiert werden, wie sie ursprünglich waren ( -a).

Der verwendete -uParameter würde vorhandene neuere Dateien überspringen, -rin Verzeichnisse zurückkehren und -vdie Ausführlichkeit erhöhen.

Kenorb
quelle
Beste Lösung aller Zeiten! In meinem Fall habe ich gerade den Parameter -u entfernt, weil ich den Stammordner nicht aktualisieren möchte. Vielen Dank
Thales Ceolin
Dies ist einer dieser Befehle, bei denen Sie, wenn Sie nicht aufpassen, unter Linux die Dinge dauerhaft durcheinander bringen können. Bitte aktualisieren Sie Ihre Antwort, um sudo vor dem Befehl rsync einzuschließen. Andernfalls können Benutzer die Berechtigung für mkdir leicht verweigern, aber das Löschen von Dateien wird trotzdem fortgesetzt. Der Befehl rsync löscht daher Ihr gesamtes Verzeichnis, das Sie verschieben möchten, und führt nichts anderes aus . Sie verlieren Ihr gesamtes Verzeichnis. Sobald Sie Ihrer Antwort sudo hinzugefügt haben, sollte dies wahrscheinlich die akzeptierte Antwort sein. Der Befehl sollte also lauten: sudo rsync -vuar --delete-after path / subfolder / path /
Blue Water
@ JohnnyB Entschuldigung für die Unannehmlichkeiten. Ich habe sudound hinzugefügt --dry-run, damit die Benutzer die Änderungen testen können, bevor sie den eigentlichen Befehl ausführen, um mögliche Probleme zu vermeiden.
Kenorb
Oh, ich wusste nicht, dass es eine --dry-run-Option gibt. Gute Ergänzung. Keine Notwendigkeit zur Entschuldigung. Das ist ausgezeichnet.
Blaues Wasser
3

Lassen Sie mich Ihnen meinen Freund "dotglob" vorstellen. Es wird ein- und ausgeschaltet, ob "*" versteckte Dateien enthält oder nicht.

$ mkdir test
$ cd test
$ touch a b c .hidden .hi .den
$ ls -a
. ..  .den  .hi .hidden a b c

$ shopt -u dotglob
$ ls *
a b c
$ for i in * ; do echo I found: $i ; done
I found: a
I found: b
I found: c

$ shopt -s dotglob
$ ls *
.den  .hi .hidden a b c
$ for i in * ; do echo I found: $i ; done
I found: .den
I found: .hi
I found: .hidden
I found: a
I found: b
I found: c

Der Standardwert ist "Aus".

$ shopt dotglob
dotglob         off

Es ist am besten, es wieder einzuschalten, wenn Sie fertig sind, sonst verwirren Sie Dinge, die davon ausgehen, dass es ausgeschaltet ist.

TomOnTime
quelle
3

Wenn Sie den findBefehl in Verbindung mit dem mvBefehl verwenden, können Sie verhindern, dass der mvBefehl versucht, Verzeichnisse (z. B. ..und .) und Unterverzeichnisse zu verschieben. Hier ist eine Option:

find /path/subfolder -maxdepth 1 -type f -name '*' -exec mv -n {} /path \;

Bei einigen anderen Antworten treten Probleme auf. Beispielsweise versucht jedes der folgenden Elemente, Unterverzeichnisse aus dem Quellpfad zu verschieben:

1) mv /path/subfolder/* /path/ ; mv /path/subfolder/.* /path/
2) mv /path/subfolder/{.,}* /path/ 
3) mv /source/path/{.[!.],}* /destination/path

Auch 2) enthält die. und .. Dateien und 3) fehlen Dateien wie ..foobar, ... barfoo usw.

Sie könnten verwenden, mv /source/path/{.[!.],..?,}* /destination/pathwas die von 3) fehlenden Dateien enthalten würde, aber es würde immer noch versuchen, Unterverzeichnisse zu verschieben. Die Verwendung des findBefehls mit dem mvoben beschriebenen Befehl beseitigt alle diese Probleme.

teancum144
quelle
2

Meine Lösung für dieses Problem, wenn ich alle Dateien (einschließlich .Dateien) in ein Zielverzeichnis kopieren muss, in dem die Berechtigungen erhalten bleiben, lautet: (überschreiben, falls bereits vorhanden)

yes | cp -rvp /source/directory /destination/directory/

yesdient zum automatischen Überschreiben von Zieldateien, rrekursiv, vausführlich und zum pBeibehalten von Berechtigungen.

Beachten Sie, dass der Quellpfad nicht mit a endet/ (daher werden alle Dateien / Verzeichnis- und. -Dateien kopiert).

Das Zielverzeichnis endet mit dem/ Platzieren des Inhalts des Quellordners auf dem gesamten Ziel.

Rajneesh Gadge
quelle
Dies yesist zwar ein großartiger Befehl, wenn Sie Zieldateien überschreiben möchten, dies ist jedoch nicht immer erwünscht. Verwenden Sie es nur, wenn Sie sicher sind, dass Sie dies tun möchten. Gibt es auch einen Unterschied zwischen yes | cp ...und cp -f ...?
Mazunki