Linux-Befehlszeile. Verschieben Sie alle Dateien und Verzeichnisse im Verzeichnis mit Ausnahme einiger Dateien und Verzeichnisse

8

Ich habe einen Ordner , Adie Dateien und Verzeichnisse hat, möchte ich alle diese Dateien und Verzeichnisse in einem anderen Ordner verschieben B, mit der Ausnahme file, file2, directory, und directory2.

Wie kann das gemacht werden?

etwas etwas
quelle

Antworten:

11

Mit zsh:

setopt extendedglob # best in ~/.zshrc
mv A/^(file|directory)(|2)(D) B/

( (D)um Punkt (versteckte) Dateien einzuschließen).

Mit bash:

shopt -s extglob dotglob failglob
mv A/!(@(file|directory)?(2)) B/

Mit ksh93

(FIGNORE='@(.|..|@(file|directory)?(2))'; mv A/* B)
Stéphane Chazelas
quelle
Ich möchte nicht einmal darüber nachdenken, wie viel Zeit Sie in jeder Shell verbracht haben müssen, um dies zu lernen! Gute Antwort!
Jpaugh
10

was ich normalerweise mache

cd A
ls > a

(vorausgesetzt, Sie haben keine 'a'-Datei).

vi a

Entfernen Sie alle Dateien oder Verzeichnisse, die an Ort und Stelle bleiben sollen.

mv $(<a) B
Archemar
quelle
Vielen Dank für die Antwort. Ich denke, einige der Experten haben möglicherweise einen Befehl / "One Liner", was weniger problematisch ist.
etwas Etwas
1
Es hängt davon ab, ob ich es einmal (meine Lösung) oder mehrmals bei Falkos Lösung tun muss.
Archemar
2
@somethingSomething Mit dieser Lösung können Sie überprüfen, was Sie gerade tun, bevor Sie es tun. Unterschätze das nicht.
Ben
1
@Ben, beachten Sie jedoch, dass Sie überprüfen müssen, ob die Dateinamen keine Leerzeichen oder Platzhalter enthalten oder nicht mit beginnen -. Sie können keine Dateinamen erkennen, die Zeilenumbrüche enthalten, und versteckte Dateien werden weggelassen.
Stéphane Chazelas
2
Dies kann aus einem weiteren Grund gefährlich sein: Wenn lses sich um einen Alias ​​für handelt ls -F(was häufig der Fall ist, wenn keine Farben verwendet werden), können Quellpfade führen /, was schwerwiegende Nebenwirkungen haben kann - siehe "Warnung" und "Nachgestellte Schrägstriche" in info mv(oder pinfo mv) aber nicht in man mv)
Volker Siegel
5

Sie können findmit ausgeschlossenen Ausdrücken verwenden:

find . ! -name . -prune ! -path ./file \
                        ! -path ./file2 \
                        ! -path ./directory \
                        ! -path ./directory2 \
     -exec mv {} your_destination \;

Diese Lösung ist von dieser Frage inspiriert .

Falko
quelle
Ich erhalte: find: unbekanntes Prädikat "-E", wenn ich Ihre Lösung kopiere und einfüge und "your_destination" entsprechend ändere.
etwas Etwas
1
@somethingSomething: Ich denke, Sie können die -EOption fallen lassen. Es kann jedoch Unterschiede zwischen unseren Systemen geben, da ich derzeit unter OSX arbeite.
Falko
2
ls | egrep -v '(file|file2|directory|directory2)' | xargs -i mv {} ../B/
kevino_17
quelle
1

Wenn ./Aund ./Bsich auf demselben Dateisystem befinden und wenn diese Dateien noch nicht vorhanden sind in ./B:

file file2 directory directory2

... dann sollte diese Operation nur atomar sein:

cd ./A; mv * ../B
for mv in file file2 directory directory2
do mv ../B/"$mv" .
done

Ist dies nicht der Fall, werden mindestens 8 zusätzliche geräteübergreifende Kopien mit den oben genannten Befehlen erstellt.

mikeserv
quelle
Keine Schale bekannt, die garantiert, dass dies wirklich atomar ist. Es sollte jedoch "wirklich sehr schnell" sein, wenn es auf dem gleichen fs ist. BEARBEITEN - das heißt, jeder mv kann atomar sein, wenn er sich auf demselben fs befindet, aber der gesamte mv ist nicht atomar
Brandin
@Brandin - Die Shell ist nicht daran beteiligt, ob es sich um eine atomare Operation handelt oder nicht. mv unlinksund renameswenn man keine Entwickler kreuzt, betrifft das im Grunde nur die Dentries, so wie ich es verstehe. Aber die Shell kommt nicht darauf an.
Mikesserv
0

$ sudo mv (Name des Quellordners) AB (Name des Zielordners)

Beispiel: Erstellen Sie ein leeres Verzeichnis in einem Unterordner. a 1) sudo mkdir -p A / {b / {a, b, c}, c, d}

2) ls A /

bcd

3) sudo mkdir B.

5) sudo mv a (Ordner) b (Ordner)

Dhamu
quelle
0

Sie können ein Bash-Array verwenden, um zu speichern, welche Sie überspringen möchten, und dann die hier gezeigte containsElementFunktion verwenden :

$ skiplist=(file file2 directory directory2)
$ for f in *; do if containsElement "$f" "${skiplist[@]}"; then continue; fi;
mv -v "$f" B; done
Brandin
quelle