Wie verschiebe ich alle Dateien in einem Verzeichnis (einschließlich der ausgeblendeten) in ein anderes Verzeichnis?
Wenn ich zum Beispiel einen Ordner "Foo" mit den Dateien ".hidden" und "notHidden" habe, wie verschiebe ich beide Dateien in ein Verzeichnis mit dem Namen "Bar"? Das Folgende funktioniert nicht, da die ".hidden" -Datei in "Foo" bleibt.
mv Foo/* Bar/
Versuch es selber.
mkdir Foo
mkdir Bar
touch Foo/.hidden
touch Foo/notHidden
mv Foo/* Bar/
Antworten:
Zsh
oder
(Lassen Sie das weg,
(N)
wenn Sie wissen, dass das Verzeichnis nicht leer ist.)Bash
Ksh93
Wenn Sie wissen, dass das Verzeichnis nicht leer ist:
Standard (POSIX) sh
Wenn Sie möchten, dass der
mv
Befehl trotz Erfolg einen Fehlerstatus zurückgibt, ist dies viel einfacher:GNU find und GNU mv
Standard finden
Wenn es Ihnen nichts ausmacht, in das Quellverzeichnis zu wechseln:
Im Folgenden erfahren Sie, wie Sie steuern, ob Punktdateien in bash, ksh93 und zsh abgeglichen werden.
Bash
Stellen Sie die
dotglob
Option ein .Es gibt auch die flexiblere
GLOBIGNORE
Variable , die Sie auf eine durch Doppelpunkte getrennte Liste von Platzhaltern setzen können, die ignoriert werden sollen. Wenn nicht gesetzt (Standardeinstellung), verhält sich die Shell so, als ob der Wert leer wäredotglob
, wenn gesetzt, und als ob der Wert leer wäre ,.*
wenn die Option nicht gesetzt ist. Siehe Dateinamenerweiterung im Handbuch. Die allgegenwärtigen Verzeichnisse.
und..
werden immer weggelassen, es sei denn,.
das Muster stimmt ausdrücklich mit dem überein.Ksh93
Stellen Sie die
FIGNORE
Variable ein . Wenn nicht festgelegt (Standardeinstellung), verhält sich die Shell so, als wäre der Wert.*
. Um.
und zu ignorieren..
, müssen sie explizit übereinstimmen (das Handbuch in ksh 93s + 2008-01-31 besagt, dass.
und..
immer ignoriert werden, aber dies beschreibt das tatsächliche Verhalten nicht korrekt).Sie können Punktedateien in ein Muster aufnehmen, indem Sie sie explizit abgleichen.
Wenn die Erweiterung leer sein soll, wenn das Verzeichnis leer ist, verwenden Sie die
N
Mustervergleichsoption:~(N)@(*|.[^.]*|..?*)
oder~(N:*|.[^.]*|..?*)
.Zsh
Stellen Sie die
dot_glob
Option ein ..
und..
werden nie abgeglichen, auch wenn das Muster.
explizit mit dem führenden übereinstimmt .Sie können Punktdateien in ein bestimmtes Muster mit dem
D
Glob-Qualifikationsmerkmal aufnehmen .Fügen Sie die
N
glob Qualifier die Erweiterung kommen leer in ein leeres Verzeichnis zu machen:*(DN)
.Hinweis: Sie können Dateinamen Expansion führen zu unterschiedlichen Aufträgen erhalten (zB
none
gefolgt von.one
gefolgt von..two
) auf der Grundlage Ihrer Einstellungen derLC_COLLATE
,LC_ALL
undLANG
Variablen.quelle
nullglob
? Es wäre sinnvoller, denmv
Befehl abzubrechen (wie fish, csh / tcsh, zsh (without(N)
) do oder bash with failglob), als einenmv /Bar/
Befehl auszuführen, der wenig Sinn ergibt ..
und..
werden nie erreicht (wie in anderen sinnvollen Schalen wie zsh, Fisch, pdksh und Derivate) , auch wenn Sie dotglob wieder aus danach drehen. (GLOBIGNORE=:; shopt -u dotglob; echo .*
wird nicht ausgegeben.
und..
). setzen Sie GLOBIGNORE auf.:..
oder.
oder:
haben Sie den gleichen Effekt.ksh93
immer ignorierend.
und..
scheint zwischenksh93k+
(wo es funktioniert) undksh93m
(wo es nicht mehr funktioniert) unterbrochen worden zu sein . Beachten Sie, dass diesksh93
der Umgebung den Wert von FIGNORE entzieht, sodass beispielsweise eine UmgebungsvariableFIGNORE='!(..)'
Chaos verursachen kann.Von
man bash
quelle
mv
dass die aufgerufene DateiFoo/*
nicht existiert. Interessanterweise wird, wennFoo
durchsuchbar, aber nicht lesbar ist und dort eine Datei aufgerufen*
wird, keine Fehlermeldung angezeigt, diese Datei wird verschoben, nicht jedoch die anderen Dateien im Verzeichnis.bash
Es hat einefailglob
Option, mit der es sich eher wie ein Glob verhältzsh
,fish
odercsh
/tcsh
und den Befehl mit einem Fehler abbricht, wenn ein Glob nicht erweitert werden kann, anstatt das falsche Verhalten, das Glob unverändert zu lassen.Ein einfacher Weg, dies zu tun,
bash
istDamit werden aber auch Verzeichnisse verschoben.
Wenn Sie alle Dateien einschließlich der ausgeblendeten verschieben möchten, aber kein Verzeichnis verschieben möchten, können Sie eine for-Schleife verwenden und testen.
for i in $(ls -d {Foo/*,Foo/.*});do test -f $i && mv -v $i Bar/; done;
quelle
Ein Weg ist zu benutzen
find
:Der
-type f
Befehl find beschränkt sich auf das Suchen von Dateien. Sie sollten die Optionen , und untersuchen-type
, um Ihren Befehl so anzupassen, dass er Unterverzeichnissen Rechnung trägt. Find hat eine lange, aber sehr hilfreiche Handbuchseite .-maxdepth
-mindepth
find
quelle
Foo/
, keine Unterverzeichnisse und andere Dateien.Versuchen Sie den Kopierbefehl
cp
:cp -r
bedeutet, dass rekursiv kopiert wird, sodass alle Ordner und Dateien kopiert werden.Mit dem Befehl
rm
remove können Sie einen Ordner entfernen:Weitere Informationen: Verschieben Sie alle Dateien von einem Verzeichnis in ein anderes .
quelle
Rsync ist eine weitere Option:
Dies funktioniert, weil in rsync der abschließende Schrägstrich
sourcedirectory/
auf den Inhalt des Verzeichnisses undsourcedirectory
der auf das Verzeichnis selbst verweist.Der Nachteil dieser Methode ist, dass rsync die Dateien erst nach dem Verschieben aufräumt, nicht das Verzeichnis. So bleibt Ihnen ein leerer Quellenverzeichnisbaum übrig. Problemumgehungen hierzu finden Sie unter:
Dateien verschieben und Verzeichnisse mit rsync löschen?
Während dies für Verschiebevorgänge möglicherweise nicht optimal ist, kann es für Kopiervorgänge äußerst nützlich sein.
quelle
Antwort für Bash / Fisch
Hier ist eine Möglichkeit, Wildcards zu verwenden:
.[!.]* ..?*
stimmt mit allen versteckten Dateien außer.
und überein..
.[!.]* ..?* *
wird mit allen Dateien (versteckt oder nicht) außer.
und übereinstimmen..
Und um das spezielle Beispiel dieser Frage zu beantworten, brauchen Sie
cd foo && mv .[!.]* ..?* * ../bar
Erläuterung
.[!.]*
Sucht nach Dateinamen, die mit einem Punkt beginnen, gefolgt von einem beliebigen Zeichen, mit Ausnahme des Punkts, optional gefolgt von einer beliebigen Zeichenfolge. Dies ist nah genug, aber es fehlen Dateien, die mit zwei Punkten wie beginnen..foo
. Um solche Dateien einzuschließen, fügen wir..?*
die Dateinamen hinzu, die mit zwei Punkten beginnen, gefolgt von einem beliebigen Zeichen, optional gefolgt von einer beliebigen Zeichenfolge.Prüfung
Sie können diese Platzhalter mit den folgenden Befehlen testen. Ich habe sie erfolgreich unter Bash und Fish ausprobiert. Sie scheitern unter sh, zsh, xonsh.
quelle
Möglicherweise können Sie auch mit Anführungszeichen nach Dateien für den Befehl move suchen und diese anzeigen. Übergeben Sie diese an mv.
Dh für versteckte Dateien
Damit
Verschiebt nur ausgewählte versteckte Dateien in
Bar
:Verschiebt alle Dateien in Foo in die Leiste seit dem '.' Der Befehl egrep fungiert als Platzhalter ohne eckige Klammern.
Der
^
Charakter stellt sicher, dass die Übereinstimmung am Anfang der Zeile beginnt.Einige Details zum
egrep
Pattern Matching finden Sie hier .Verwenden Sie
maxdepth 1
Stopps, um nicht in Unterverzeichnisse zu gelangen.quelle
Inspiriert von dieser Antwort :
Ohne die Dateien zu kopieren ...
Vorsichtsmaßnahmen:
--link-dest
Pfad muss absolut oder relativ zu DESTINATION sein (Bar
im Beispiel)Sie müssen
/
nach SOURCE (Foo/
im Beispiel) einfügen , andernfalls wird der SOURCE-Ordner anstatt dessen Inhalt kopiert.quelle
Ich finde, dass dies gut für Bash funktioniert und es keine Notwendigkeit gibt, die Shell-Optionen zu ändern
BEARBEITEN:
Wie G-man feststellte, ist meine ursprüngliche Antwort nicht posix-konform und entspricht in etwa der obigen Antwort von ndemou mit einer Änderung, nämlich der Verwendung der geschweiften Klammer, um Listen von Zeichenfolgen zu erstellen, auf die dann reagiert wird. Dies bedeutet nur, dass Sie nicht
cd
in das Quellverzeichnis müssen. Eigentlich keine große Veränderung, aber es ist anders.Beispiel: Nehmen wir an, Sie haben bereits das folgende Layout.
Die ursprüngliche Frage bezog sich nur auf versteckte Dateien mit einem einzigen Punkt. Nehmen wir jedoch an, dass am Anfang des Namens zwei oder mehr Punkte stehen. Sie können einfach einen zusätzlichen Ausdruck in die geschweiften Klammern einfügen. Wir können dann ausführen
Dies wird folgendermaßen erweitert:
Sie sollten jetzt alle Dateien in destdir sehen :
Sie können mit geschweiften Klammern in bash einige ziemlich coole Dinge tun, mit noch mehr Ergänzungen in 4.x. Schauen Sie sich Bash-Hacker an, um einige nützliche Beispiele zu finden.
quelle
..
, und (2) um POSIX-kompatibel zu sein , sollten Sie!
statt verwenden^
; dh{*,.[!.]*}
.cd
in das Quellverzeichnis wechseln muss, um auf die Dateien zuzugreifen oder immer wieder dieselben Dateipfade zu schreiben, um die Pfade zu allen Dateien auszudrücken. Ich werde das Beispiel in Kürze aktualisieren, um den Lesern ein besseres Bild davon zu geben, wovon ich spreche.Für minimale Linux-Distributionen sollte Folgendes funktionieren. Führen Sie zunächst einen einfachen Move all aus (bei dem die versteckten Dateien fehlen). Dann bewegen Sie alle versteckten Dateien (einschließlich der
.
und..
die wird nicht tatsächlich bewegt werden).Hinweise: Wenn kein sichtbarer Inhalt vorhanden ist, wird beim ersten Befehl eine Fehlermeldung ausgegeben. Der zweite Befehl erzeugt immer einen Fehler, der besagt, dass er sich nicht bewegen kann
.
und..
. Als solches leiten Sie die Fehler einfach weiter/dev/null
(wie gezeigt).Wenn Sie dies als Einzeiler benötigen, kombinieren Sie diese einfach mit einem Semikolon:
quelle