Wie verschiebe ich nur die Dateien im aktuellen Ordner in einen Unterordner?

9

Ich muss nicht die Ordner verschieben, nur die Dateien.

Ich habe es versucht, mv *aber dieser Befehl verschiebt auch die Ordner.

Archit
quelle

Antworten:

13

Wenn Sie alles außer Verzeichnissen von $SOURCE_DIRnach verschieben möchten $TARGET_DIR, können Sie diesen Befehl verwenden:

find "$SOURCE_DIR" -maxdepth 1 -not -type d -exec mv -t "$TARGET_DIR" -- '{}' +

Im Detail erklärt:

  • find: Die Suche nach Dateien in einem Verzeichnis suchen
  • $SOURCE_DIR: Das Verzeichnis, in dem gesucht werden soll
  • -maxdepth 1: Schauen Sie nicht in Unterverzeichnisse
  • -not -type d: Verzeichnisse ignorieren
    • Sie können es auch verwenden, -type fwenn Sie nur Dinge kopieren möchten, bei denen es sich ausschließlich um Dateien handelt. Ich bevorzuge jedoch das Obige, da es auch alles abfängt, was weder eine Datei noch ein Verzeichnis ist (insbesondere symbolische Links).
  • -exec mv -t "$TARGET_DIR" -- '{}' +: Führen Sie den Befehl aus, mv -t "$TARGET_DIR" -- FILES...in dem FILES...sich alle übereinstimmenden Dateien befinden (danke @DavidFoerster).
Frxstrem
quelle
2
find ... -exec mv -t "$TARGET_DIR" -- '{}' +wäre sicherer (falls $TARGET_DIRkein Verzeichnis vorhanden ist oder die Übereinstimmung mit beginnt -) und effizienter (da nicht für jede übereinstimmende Datei ein neuer Unterprozess erzeugt wird).
David Foerster
@ DavidFoerster Danke, aktualisiert (auch heute etwas Neues gelernt!)
Frxstrem
5

Ich denke, Sie möchten nur Ihre Dateien mv. Gehen Sie zuerst in Ihr Verzeichnis und verwenden Sie diesen Befehl, ersetzen Sie $ TARGET durch Ihren Zielverzeichnispfad. Wenn Sie Ihre Dateien kopieren möchten, ersetzen Sie sie mvdurch cp.

find . -type f -exec mv {} $TARGET \;

Wenn ich dies erkläre, find . -type fbedeutet dies, dass Sie alle Dateien auswählen und den Befehl für alle ausgewählten Elemente -exec mv {} $TARGET \;ausführen mv.


Die vorherige Antwort hat einen Fehler. Es werden auch mvalle Dateien in Unterverzeichnissen angezeigt. Die schnelle Lösung ist Verwendung -maxdepth 1. Dann werden keine rekursiven mvDateien in Unterverzeichnissen gespeichert. Unten ist die richtige ..

find . -maxdepth 1 -type f -exec mv {} $TARGET \;
Emalsha Rasad
quelle
Ich glaube nicht, dass der Fragesteller das will! Außerdem werden alle Dateien in Unterverzeichnissen in dasselbe Zielverzeichnis verschoben. Das -type fverhindert keine Rekursion.
Martin Thornton
@ MartinThornton danke für Ihren Vorschlag .. Ich werde meine Antwort bearbeiten ...
Emalsha Rasad
3

Python-Ansatz

Wenn Sie rekursiv mit Dateien umgehen, findist dies der richtige Weg. In diesem speziellen Fall ist es nicht notwendig, kann aber verwendet werden, -maxdepth 1wie andere Antworten zeigen.

Ein einfacher Python-Befehl kann dies ebenfalls tun. Hier ist ein Beispiel:

$ tree
.
├── a_directory
└── a_file

$ python -c "import os,shutil;fl=[f for f in os.listdir('.') if os.path.isfile(f)];                                      
> map(lambda x:shutil.move(x,'./a_directory'),fl)"

$ tree
.
└── a_directory
    └── a_file

1 directory, 1 file

So funktioniert das:

  • fl=[f for f in os.listdir('.') if os.path.isfile(f)]iteriert über alle gefundenen Elemente os.listdir('.')und wir testen mithilfe der os.path.isfile()Funktion, ob es sich bei dem Element um eine Datei handelt .

  • Sobald die flDateiliste erstellt ist, verwenden wir die map()Funktion. Diese Funktion akzeptiert zwei Argumente - eine Funktion und eine Liste von Elementen. Es wird die Funktion ausführen, die wir für jede Datei in einer Liste angegeben haben. Wir haben hier also lambda x:shutil.move(x,'./a_directory')eine anonyme Funktion, die eine bestimmte Datei in ein bestimmtes Verzeichnis verschiebt, und dann haben wir fldie Liste der Dateien, die wir erstellt haben.

Aus Gründen der Lesbarkeit und allgemeinen Verwendung können wir dies auch als allgemeines Python-Skript umschreiben, das zwei Argumente verwendet - Quellverzeichnis und Ziel-Unterverzeichnis.

#!/usr/bin/env python3
from os import listdir
from os.path import isfile,realpath
from os.path import join as joinpath
from shutil import move
from sys import argv

# this is script's full path
script=realpath(__file__)
# get all items in a given directory as list of full paths
fl=[ joinpath(argv[1],f) for f in listdir(argv[1]) ] 
# filter out script itself ( just in case) and directories
fl_filtered = [ f for f in fl if isfile(f) and not script == realpath(f) ]
# Uncomment this in case you want to see the list of files to be moved
# print(fl_filtered)
# move the list of files to the given destination
for i in fl_filtered:
     move(i,argv[2])

Und die Verwendung ist wie folgt:

$ tree
.
├── a_directory
├── a_file
└── files2subdir.py

1 directory, 2 files

# Notice: the script produces no output unless you uncomment print statement
$ ./files2subdir.py "." "./a_directory"                                                                                  

$ tree
.
├── a_directory
│   └── a_file
└── files2subdir.py
Sergiy Kolodyazhnyy
quelle
Hier ist ein weiterer Python-Ansatz
jfs
3

Wenn Sie zsh anstelle von bash verwenden, können Sie Folgendes tun:

mv "$SOURCE"/*(.) "$TARGET"

Das (.)am Ende wird als Glob-Qualifier bezeichnet. Das .Innere bedeutet speziell, nur reguläre Dateien abzugleichen.

Ein zu machen mv *(.) "$target"ist schnell und praktisch. Wenn Sie dies jedoch als Teil eines Skripts tun, sollten Sie stattdessen etwas schreiben, wie es Frxstrem und David Forester vorgeschlagen haben mv -t "$target" -- *(.), um Eckfälle besser zu behandeln, die bei der Verwendung durch andere Personen auftreten können.

JoL
quelle
1
Wie David Forester auf meine Antwort hinwies, mv -t "$TARGET" -- "$SOURCE"/*(.)wäre dies sicherer (falls "$TARGET"mit -einem Verzeichnis begonnen wird oder nicht). Ich mag die zsh-Lösung!
Frxstrem
2

So verschieben Sie in Python alles außer Verzeichnissen von source-dirVerzeichnis zu destination-dirVerzeichnis:

#!/usr/bin/env python3
"""Usage: mv-files <source-dir> <destination-dir>"""
import shutil
import sys
from pathlib import Path

if len(sys.argv) != 3:
    sys.exit(__doc__)  # print usage & exit 1
src_dir, dest_dir = map(Path, sys.argv[1:])
for path in src_dir.iterdir():
    if not path.is_dir():
        shutil.move(str(path), str(dest_dir / path.name))

Siehe Ausführen der Python-Datei im Terminal .

jfs
quelle
@SergiyKolodyazhnyy Ich sehe eine solche Anforderung in pep-8 nicht und (gemäß dem Beispiel dort) ist es genau das Gegenteil: import mypackagevorfrom mypackage import ...
jfs
@SergiyKolodyazhnyy verwechseln nicht die speziellen from __future__Importe und gewöhnlichen from pathlibImporte.
JFS
Ja, es sieht so aus, als hätte ich diesen Teil falsch verstanden. Nein, Sie haben Recht, import modulesollte der erste sein ( from module import object
dh
0

Ich würde verwenden

mv *.*

Dies funktioniert, solange Ihre Ordner keine Erweiterungen haben.


quelle