Verschieben Sie alle Dateien bis auf eine


154

Wie kann ich alle Dateien außer einer verschieben? Ich suche so etwas wie:

'mv ~/Linux/Old/!Tux.png ~/Linux/New/'

wo ich alte Sachen in neue Sachen-Ordner außer verschieben Tux.png. ! -Zeichen steht für eine Negation. Gibt es ein Werkzeug für den Job?

Antworten:


142

Wenn Sie bash verwenden und die extglobShell-Option festgelegt haben (was normalerweise der Fall ist):

mv ~/Linux/Old/!(Tux.png) ~/Linux/New/

1
Ich habe etwas falsch gemacht, als ich den Befehl für viele Elemente getestet habe: mv ~ / Linux / Old /! (Tux.png Tux1.png Tux2.png) ~ / Linux / New / Es leert das gesamte Old-Verzeichnis. Was ist falsch?
Léo Léopold Hertz 준영

5
@ UnixBasics, versuchen Sie: ~ / Linux / Old /! (Tux.png | Tux1.png | Tux2.png)
Juliano

@ Juliano Sehr cooler Befehl! Gibt es mehr mathematische Operationen wie OR und XOR? Ich nehme an, eine Pipe ist für UND.
Léo Léopold Hertz 준영


@ Juliano Ich bin ziemlich verwirrt von den Mustern wie: mv ~ / Linux /? (Tux * .png) ~ / Linux / Neu / mv ~ / Linux / + (Tux * .png) ~ / Linux / Neu / Im ersteren Ich wollte 0-1 Tux-Foto bewegen. In letzterem wollte ich 1-n Tux-Fotos verschieben. Sie bewegten alles. Warum? Ist es möglich, eine bestimmte Anzahl von Fotos zu verschieben?
Léo Léopold Hertz 준영

96

Fügen Sie Folgendes in Ihre .bashrc ein

shopt -s extglob

Es erweitert reguläre Ausdrücke. Sie können dann alle Dateien außer einer um verschieben

mv !(fileOne) ~/path/newFolder

Ausnahmen in Bezug auf andere Befehle

Beachten Sie, dass beim Kopieren von Verzeichnissen der Vorwärtsblitz nicht im Namen verwendet werden kann, wie im Thread angegeben. Warum extglob außer brechen außer Bedingung? ::

cp -r !(Backups.backupdb) /home/masi/Documents/

Das Backups.backupdb/ist hier vor der Negation falsch und ich würde es auch nicht zum Verschieben von Verzeichnissen verwenden, da das Risiko besteht, dass Globs mit anderen Befehlen und möglichen anderen Ausnahmen falsch verwendet werden.


3
Dies ist eigentlich die richtige Antwort. Meins war völlig falsch; Zum Glück hatte ich es in einem Ordner mit nur wenigen Dateien verwendet. Hier finden Sie weitere Informationen zu der Methode, die Masi zeigt: wiki.bash-hackers.org/syntax/pattern Gehen Sie zu "Erweiterte Mustersprache" und Sie finden weitere Informationen dazu. Vielen Dank an @ paul-whittaker für den Hinweis auf das Problem.
Mimoralea

Dies ist eine alte Antwort, aber sie ist immer noch gültig. Ich verwende Ubuntu 18 und extglob scheint standardmäßig aktiviert zu sein (ich habe es nicht ausgewählt). Ich habe den folgenden Befehl verwendet, um alle Dateien im aktuellen Verzeichnis in ein Archiv zu verschieben, das sich ebenfalls in diesem Verzeichnis befindet, ohne andere mv !(arc*) archive_190629b
Archivordner einzuschließen

70

Ich würde mit dem traditionellen Find & Xargs-Weg gehen:

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png -print0 | 
    xargs -0 mv -t ~/Linux/New

-maxdepth 1macht es nicht rekursiv zu suchen. Wenn Sie sich nur für Dateien interessieren, können Sie sagen -type f. -mindepth 1bewirkt, dass der ~/Linux/OldPfad selbst nicht in das Ergebnis aufgenommen wird. Funktioniert mit allen Dateinamen, auch mit solchen, die eingebettete Zeilenumbrüche enthalten.

Ein Kommentar stellt fest, dass die -tOption mv wahrscheinlich eine GNU-Erweiterung ist. Für Systeme, die es nicht haben

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png \
    -exec mv '{}' ~/Linux/New \;

1
Upvoted, da es das Erlernen eines mächtigen Werkzeugs fördert, finden. Beachten Sie, dass dies bei Dateien mit Leerzeichen nicht funktioniert. Betrachten Sie "find -print0 | xargs -0" oder verzichten Sie auf xargs: "find [was Sie gesagt haben] -exec mv -t {} ~ / Linux / New \;"
JasonSmith

Wenn Ihr Befehl mv nicht über die Option -t verfügt, verwenden Sie entweder "find ... -exec mv {} Linux / New \;" oder "find ... | xargs -I {} mv {} Linux / New". Die Option -t scheint eine GNU-Erweiterung zu sein, die für Linux in Ordnung ist, aber wahrscheinlich nicht anderswo.
Rob Kennedy

jhs, oh ich versage. Ich dachte irgendwie, Xargs spalten sich an Zeilenumbrüchen, aber nicht an Leerzeichen. sieht aus wie ich es mit "lesen" verwechselt habe :) Ich werde es reparieren
Johannes Schaub - litb

Vielen Dank für den tollen Tipp! Ich wollte etw wählen, weil es auf die Frage abzielt. Ich kann jedoch später die Nützlichkeit Ihrer Befehle spüren, daher muss ich den Weg "find and xargs" wählen. Es rockt einfach. Danke :)
Léo Léopold Hertz 26

Viel zu kompliziert. Die Antwort von Masi ist vollständiger, einfacher und daher korrekter
user637338

30

Eine schnelle Möglichkeit wäre, den Tux-Dateinamen so zu ändern, dass Ihr Verschiebungsbefehl nicht übereinstimmt.

Beispielsweise:

mv Tux.png .Tux.png

mv * ~/somefolder

mv .Tux.png Tux.png

Verwenden Sie nicht " . ", da dadurch nur Dateien mit einem "." verschoben werden. im Namen. Nur "*" ist genug.
Juliano

1
Wenn Sie es in * ändern, wird auch Ihre umbenannte Datei entfernt.
John T

6
@ John T: Nein, der * glob stimmt nicht mit Dateien überein, die mit dot beginnen.
Bill Karwin

Dies ist bei weitem die beste Antwort. Diese Antwort muss nicht geändert oder kommentiert werden. 100 Punkte. Vielen Dank. Gut gemacht!
Steve K

22

Ich denke, der einfachste Weg ist mit Backticks

mv `ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Bearbeiten:

Verwenden Sie stattdessen einen Backslash mit ls, um die Verwendung mit Alias ​​zu verhindern, dh meistens wird ls als ls --color aliasiert.

mv `\ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Danke @Arnold Roa


1
Können Sie bitte erklären, warum Sie grep -vdort verwenden?
Léo Léopold Hertz 준영

-v Option in grep schließt das Ergebnis aus, es ist wie alles außer Tux.png zu nehmen
Rohail Abbas

1
Dies ist sicherlich intuitiv, aber die obigen Antworten sind besser. Wenn Sie beispielsweise ein Skript schreiben, müssen Sie sich im richtigen Verzeichnis befinden.
nJGL

@nJGL Wir können hier auch einen absoluten Pfad angeben, ich habe Homedirectory (~) verwendet, da die Frage dies hatte
Rohail Abbas

@RohailAbbas Fair genug. ✌️
nJGL

14

Für Bash ist etw Antwort richtig. Hier ist die zsh- Syntax (meine Shell der Wahl):

mv ~/Linux/Old/^Tux.png ~/Linux/New/

Erfordert EXTENDED_GLOBdie Einstellung der Shell-Option.


3
Was ist, wenn wir zwei Dateien ausschließen möchten?
Mpen

13

Ich finde das etwas sicherer und einfacher, wenn man sich auf einfache Verschiebungen verlässt, die bestimmte Dateien oder Verzeichnisse ausschließen.

ls -1 | grep -v ^$EXCLUDE | xargs -I{} mv {} $TARGET

Dies ist die beste Lösung für Busybox / ASH
Stuart Cardall

1
Dies funktionierte für mich in einer Situation, in der ich alle Dateien außer wenigen Ordnern in ein anderes Verzeichnis verschieben musste
Umar Hayat

Die -lOption, lsviele irrelevante Informationen in die Befehlszeile aufzunehmen und den Befehl mv fehlzuschlagen.
jdhao

5

Das Folgende ist keine 100% garantierte Methode und sollte überhaupt nicht für die Skripterstellung versucht werden. Manchmal ist es jedoch gut genug für eine schnelle interaktive Shell-Nutzung. Eine Datei Datei Glob wie

[abc]*

(die alle Dateien mit Namen abgleichen, die mit a, b oder c beginnen) kann negiert werden, indem zuerst ein "^" - Zeichen eingefügt wird, d. h

[^abc]*

Ich benutze dies manchmal, um nicht mit dem Verzeichnis "lost + found" übereinzustimmen, wie zum Beispiel:

mv /mnt/usbdisk/[^l]* /home/user/stuff/.

Wenn es andere Dateien gibt, die mit l beginnen, muss ich diese natürlich später verarbeiten.


4
mv `find Linux/Old '!' -type d | fgrep -v Tux.png` Linux/New

Der Befehl find listet alle regulären Dateien auf und der Befehl fgrep filtert alle Tux.png heraus. Die Backticks weisen mv an, die resultierende Dateiliste zu verschieben.


4
Bewerten Sie find niemals als Argumente für einen anderen Befehl. Es werden schlimme Dinge passieren. Möglicherweise haben Sie gerade eine Sicherheitsanfälligkeit erstellt. Verwenden Sie immer den find -print0 | xargs -0 Konstrukt oder find -exec.
Juliano

3

Wie wäre es, wenn Sie alles in den Ordner verschieben und dann einfach Tux.png zurück verschieben?

Ich kann mir keine Shell-Syntax vorstellen, die "alles außer ..." ohne weiteres sagt.


3
ls ~/Linux/Old/ | grep -v Tux.png | xargs -i {} mv ~/Linux/New/'

1
Dieser Befehl scheint einen Teil zu vermissen und funktioniert auf meinem Computer nicht. ls ~/Linux/Old/ | grep -v Tux.png | xargs -I{} mv {} ~/Linux/New/funktioniert stattdessen.
Katherine Chen

3

Wie wäre es mit:

mv $(echo * | sed s:Tux.png::g) ~/Linux/New/

Sie müssen sich jedoch im Ordner befinden.


3

Man kann grep so überspringen :

ls ~/Linux/Old/ -QI Tux.png | xargs -I{} mv ~/Linux/Old/{} ~/Linux/New/

1

Dies könnte einfacher und leichter zu merken sein und es funktioniert für mich.

mv $(ls ~/folder | grep -v ~/folder/exclude.png) ~/destination

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.