Wie kann ich mv (oder den Platzhalter *) dazu bringen, versteckte Dateien zu verschieben?

133

Ich migriere mein Home-Verzeichnis von einem alten auf ein neues System, und der von mir erstellte Tarball enthält alles, einschließlich versteckter Dateien wie .bashrc. Wenn ich jedoch den Inhalt des entpackten Tarballs (der sich in / tmp befindet) in mein neues Ausgangsverzeichnis verschiebe, werden die versteckten Dateien nicht kopiert ( mv /tmp/home/rcook/* /home/rcook/). Wie kann ich mv dazu bringen, sie zu bewegen?

Eigentlich glaube ich, dass das Problem nicht bei mv liegt, sondern bei bashs Globbing. Wenn ich das mache:

mkdir a
mkdir b
touch a/.foo
touch a/bar
mv a/* b/
ls -a a/ b/

Ich sehe es:

a/:
.  ..  .foo

b/:
.  ..  bar

a/.foobewegte sich nicht. Wie kann ich den Platzhalter * zum Auffinden versteckter Dateien verwenden?

Ja, ich nehme an, ich könnte den Tarball direkt in mein Home-Verzeichnis dekomprimieren, aber der Tarball wird in dekomprimiert home/rcook/..., und ich möchte sicher sein, dass ich den neuen .bashrcusw. mit den alten angepassten Versionen überschreibe und weiß, wie man versteckte Dateien findet und verschiebt ist eine lohnende Fähigkeit. Vorschläge?


Einige Antworten schlagen vor, so etwas zu tun mv src/.* dest/. Ich habe dies jedoch in meinen Testverzeichnissen versucht und Fehler festgestellt. Beginnen mit:

rcook$ ls -a a/ b/
a/:
.  ..  bar  .foo

b/:
.  ..
rcook$ mv a/.* b/
mv: cannot move 'a/.' to 'b/.': Device or resource busy
mv: cannot remove 'a/..': Is a directory
rcook$ ls -a a/ b/
a/:
.  ..  bar

b/:
.  ..  .foo

Was mache ich falsch?

Randall Cook
quelle

Antworten:

146

Du kannst das :

shopt -s dotglob
mv /tmp/home/rcook/* /home/rcook/

Du kannst Geben

shopt -s dotglob

in Ihrem, ~/.bashrcwenn Sie möchten, dass es die Standardeinstellung ist.

Siehe http://mywiki.wooledge.org/glob


Ein anderer Ansatz zum Kopieren der Punktedateien:

mv /tmp/home/rcook/.[!.]* /home/rcook/

Verwenden Sie das Muster nicht so, ..*wie es passt ..(Zeiger auf das übergeordnete Verzeichnis). Wenn es Dateien gibt, deren Name mit zwei Punkten ( ..something) beginnt , verwenden Sie auch das Muster ..?*.

Gilles Quenot
quelle
Bitte beachten Sie die Ergänzungen, die ich am Ende meiner Frage angeführt habe. Vielen Dank.
Randall Cook
1
Nothings falsch, .und ..ist specials dirs: jeweils aktuelles Verzeichnis & Elternverzeichnis . Es ist nur eine Warnung. Bessere shopt -s dotglobLösung
Gilles Quenot
Am Ende habe ich nur zwei Züge gemacht: mv home/rcook/* /home/rcook/gefolgt von mv home/rcook/.* /home/rcook/. Dies hat den Trick gemacht, obwohl ich wünschte, ich wäre dem Link gefolgt und hätte zuerst etwas über den Dotglob-Modus gelesen. Es hätte mich einen Schritt gerettet. +1
Randall Cook
Der zweite Ansatz erfordert also die Verwendung absoluter Pfade?
Franzlorenzon
3
Wenn Sie verwenden zsh, können Sie das DGlobbing-Qualifikationsmerkmal oder die GLOB_DOTSShell-Option verwenden .
mgalgs
43

In Ihren Ergänzungen haben Sie Fehler erhalten, aber der Code hat noch funktioniert. Das einzige, was Sie hinzufügen müssen, ist, dass Sie angegeben haben, dass nur die Punktedateien kopiert werden sollen. Versuchen:

mv src/* src/.* dst/

Sie erhalten weiterhin die Fehler für die. und .. Einträge, was in Ordnung ist. Aber der Umzug sollte gelingen.

~/scratch [andrew] $ mv from/* from/.* to/
mv: cannot move from/.’ to to/.’: Device or resource busy
mv: cannot remove from/..’: Is a directory
~/scratch [andrew] $ ls -a from/ to/
from/:
.  ..

to/:
.  ..  test  .test
Andrew Schwartz
quelle
1
Gute Punkte, @AndrewSchwartz. Ich mag diesen Ansatz auch. Ich denke, es verdient mehr Anerkennung.
Randall Cook
Ich mag die Antwort von @Drake Clarris etwas mehr, da ich auf Amazon AWS CodeBuild arbeite und der Rückkehrcode ungleich Null tatsächlich dazu führte, dass mein Build gestoppt wurde. Am Ende habe ich die eine .hiddenDatei verschoben, die ich explizit hatte, um mein Problem zu lösen.
HeyWatchThis
Wenn der Exit-Code ungleich Null ein Problem ist, können Sie ihn unterdrücken, z. B. durch Anhängen || :( ||bedeutet, bei false / error Folgendes ausführen, :ist noop-Befehl). Das würde aber auch legitime Fehler unterdrücken, zB Zielordner existiert nicht. Ich kann keinen eleganteren Weg finden mv, um die .und ..-Einträge auszuschließen . Hintern großes Plus für mich über CP schreibt keine neuen Dateien auf die Festplatte.
Andrew Schwartz
10

Wenn Sie sich ls -lin einem Verzeichnis befinden, sehen Sie .und ..unter aufgelisteten Dateien. Also, ich denke, mv .* /destberücksichtigt diese Hinweise. Versuchen:

mv /tmp/home/rcook/{*,.[^.]*,..?*} /home/rcook/

Dadurch werden die aktuellen und übergeordneten Verzeichniszeiger ignoriert.

Sie erhalten einen Fehler , wenn eine der drei Muster erhalten *, [^.]*oder ..?*passen keine Datei, so dass Sie sollten nur schließen diejenigen , die passen.

Azamat
quelle
Nett. Eine ähnliche Antwort für diesen Globbing-Stil finden Sie hier: superuser.com/a/784046/144977 . Danke, dass du das gepostet hast.
Phyatt
7

Zwei mögliche Lösungen, die ich mir vorstellen kann. Die erste besteht darin, stattdessen cp mit seiner rekursiven Option zu verwenden und das aktuelle Verzeichnis in das Zielverzeichnis zu kopieren.

cp -Rp . /desired/directory

dann können Sie die Quelldateien im aktuellen Verzeichnis entfernen

Wenn Sie wissen, dass die Dateien einen korrekten Namen haben (keine Leerzeichen, Platzhalter, nicht druckbare Zeichen), können Sie auch so etwas tun

mv $(ls -A) /desired/directory
Drake Clarris
quelle
4
Das Kopieren und Entfernen unterscheidet sich erheblich vom Verschieben, wenn sich Quelle und Ziel auf demselben Dateisystem befinden. Fügen Sie mindestens die Option -pzum Beibehalten von Metadaten hinzu. Verwenden lssollte ein letzter Ausweg sein, und hier gibt es bessere, einfachere Wege.
Gilles
2

Unter Linux gibt es eigentlich keine "versteckten" Dateien. Dateien, die mit einem Punkt beginnen, werden standardmäßig nur in den Dateilisten ausgeblendet.

Um Dateien auch mit einem glob zu kopieren, müssen Sie die Datei mit Präfix .wie mv -u .* foound dann .foowerden appearn als foo/.foowenn er bewegt wird .

Die Option -u verschiebt die Dateien nur, wenn die Quelle neuer ist oder das Ziel fehlt. Oder Sie könnten nur die Fehler ignorieren zu bewegen .und ..wie sie spezielle Dateien sind und können nicht verschoben werden, aber nicht in dem gefangen .*von dem Shell Glob.

dobey
quelle
Bitte beachten Sie die Ergänzungen, die ich am Ende meiner Frage angeführt habe. Vielen Dank.
Randall Cook
0

Also haben wir:

a
|-- .foo
`-- bar

und:

b

Ich habe mir sehr viel Zeit genommen, um eine bessere Lösung zu finden als alle Antworten hier.

Dann habe ich 30 Sekunden für diesen Befehl gebraucht:

$ mv --help

Dann habe ich meine Liebe gefunden:

$ mv a/ b/ -T

Hinweis: Ich verstehe das Argument nicht einmal -T. Es hat einfach getan, was ich brauchte. Hier heißt es:

-T, --no-target-directory behandelt DEST als normale Datei

user433901
quelle
1
Wenn Sie die Schrägstriche weglassen, sollten Sie nicht brauchen -T. In beiden Fällen bedeutet dies im Wesentlichen, dass mv das Verzeichnis selbst und nicht alle darin enthaltenen Dateien verschieben soll.
Thomasrutter
@thomasrutter, ist das Verschieben des Verzeichnisses nicht dasselbe wie das Umbenennen?
Randall Cook
3
Ja, wenn das übergeordnete Ziel dasselbe bleibt, wird es im Wesentlichen nur umbenannt. Wie auch immer Sie sich darauf beziehen, es hilft wahrscheinlich nicht, die ursprüngliche Frage zu beantworten, bei der es darum ging, die Dateien innerhalb des Verzeichnisses an einen bestimmten Ort zu verschieben.
Thomasrutter
0

In meinem Fall habe ich einfach versucht, mveine einzelne versteckte Datei zu finden, und dies war die Lösung:

FILE=.myHiddenFile
mv "$FILE" dest/

Erläuterung

Zuerst habe ich versucht:

mv .myHiddenFile dest/

Aber es verursachte weiterhin den Fehler:

mv: cannot stat '.myHiddenFile': No such file or directory

Obwohl ein ls -alzeigte, dass die Datei und dest/existierte.

Der Grund scheint darin zu liegen, dass die Shell das "." Wenn Sie die Datei also in eine Variable verschieben, wird die Interpretation vermieden. Es gibt wahrscheinlich andere Möglichkeiten, dies zu lösen, aber das hat uns gereicht.

Jesaja
quelle
-1

Wenn Sie Dateien einschließlich versteckter Dateien in das aktuelle Verzeichnis kopieren möchten, in dem Sie sich befinden.

cp -Rp source-directory/. .
Rick
quelle
1
Dies ist der Antwort von Drake Clarris aus dem Jahr 2013 sehr ähnlich. Haben Sie noch etwas hinzuzufügen?
Randall Cook