Ich möchte Dateien innerhalb eines lexikografischen Bereichs kopieren.
Beispiel für Dateien:
-rw-r--r-- 1 root root 15276 Oct 5 2004 a2ps.cfg
-rw-r--r-- 1 root root 2562 Oct 5 2004 a2ps-site.cfg
-rw-r--r-- 4 root root 4096 Feb 2 2007 acpi.txt
-rw-r--r-- 1 root root 48 Feb 8 2008 adjtime.jpg
-rw-r--r-- 4 root root 4096 Feb 2 2007 alchemist.jpg
Anwendungsbeispiel:
- Kopieren Sie die 3 Dateien von
asps.cfg
nachacpi.txt
- Kopieren Sie die 3 Dateien von
a2ps-site.cfg
nachadjtime.jpg
- Kopieren Sie die 4 Dateien von
a2ps-site.cfg
nachalchemist.jpg
Gibt es also eine Möglichkeit, eine Reihe von Dateien (von Dateiname X bis Dateiname Y) in ein Verzeichnis zu kopieren?
Mögen: cp filenameX ... filenameY destination/
Antworten:
Ein allgemeiner Ansatz besteht darin, eine Shell-Funktion zu definieren, die eine Reihe von Dateinamen druckt. In einer einfachen Version dieser Funktion werden alle Dateien zwischen zwei Dateinamen einschließlich im aktuellen Verzeichnis aufgelistet:
Hierbei wird ein sed-Bereich verwendet, um etwas zwischen den beiden angegebenen Zeichenfolgen (
$1
und$2
) auszudrucken .Sie können diese Funktion dann in Ihrem
cp(1)
Befehl verwenden:Dies schlägt fehl, wenn Sie Dateinamen mit Leerzeichen haben. Dafür müssen Sie etwas komplizierter werden:
Dies schlägt fehl, wenn Ihre Dateinamen Zeilenumbrüche (\ n) enthalten. Das ist sehr unwahrscheinlich, daher bleibt das Reparieren eine Übung für den Leser.
Sie könnten das zusammen in eine andere Shell-Funktion rollen:
und benutze es wie:
Denken Sie daran, dass der Bereich nur für Dateinamen im aktuellen Verzeichnis funktioniert. Sie können dies auf verschiedene Arten erweitern (zusätzliche Verzeichnisparameter
range
, Extrahieren eines Pfads aus Argumenten zurrange
Verwendungdirname
usw.), aber das überlasse ich Ihnen basierend auf Ihren Anforderungen. Bitte fragen Sie, ob Sie hier weitere Details wünschen.quelle
source range.sh
Zsh bietet eine einfache Möglichkeit, eine Reihe von Dateien aus dem Ergebnis eines Globs auszuwählen (ein Glob ist eine Platzhalterübereinstimmung). Auf der positiven Seite ist der Befehl sehr kurz zu schreiben. Auf der Minus-Site müssen Sie die Ordnungszahlen der Dateien herausfinden, die Sie schreiben möchten. Der folgende Befehl kopiert beispielsweise die 21., 22.,…, 40. Datei mit einer
.jpg
Erweiterung im aktuellen Verzeichnis, wobei die Dateien in alphabetischer Reihenfolge aufgelistet sind:Zsh hat eine Option , die nicht hilfreich sein kann oder Sie da : unter
setopt numeric_glob_sort
,foo9bar.jpg
wird vor dem sortiert werdenfoo10bar.jpg
. Sie können auch eine andere Sortierreihenfolge in den Glob-Qualifikationsmerkmalen auswählen, z. B.cp *.jpg(om[21,40]) destination/
um die 21. bis 40. neuesten Dateien auszuwählen (verwenden Sie ein GroßbuchstabenO
, um in der entgegengesetzten Reihenfolge zu sortieren). Weitere Informationen finden Sie unter Glob-Qualifikationsmerkmale im Handbuch.Unter jeder Shell können Sie eine Schleife schreiben, die die Dateien durchläuft, mit dem Kopieren bei der ersten Datei beginnt, die Sie schreiben möchten, und nach der letzten Datei stoppt. Warnung, ungetestet.
quelle
In diesem Beispiel ist es am einfachsten, M- * zu verwenden, um Ihr Muster zu vervollständigen und diejenigen zu entfernen, die Sie nicht kopieren möchten.
und dann einfach manuell die Dateien entfernen, die Sie nicht kopieren möchten. Wie auch immer, dies ist eine Shell-Funktion, keine
cp
.Sie können das Muster beliebig verfeinern. Wenn Sie viele andere Dateien im Verzeichnis hatten und nur diejenigen kopieren möchten, die mit beginnen
a
, beginnen Sie das Muster einfach mit diesem Buchstaben. Möglicherweise möchten Sie die Dokumentation der Shell zum Dateinamen-Globbing nachschlagen. Zum Beispiel http://tldp.org/LDP/abs/html/globbingref.html .quelle
Es scheint, dass Dateinamen sortiert sind und Sie in gleichen Mengen verteilen.
Holen Sie sich alle Dateinamen in eine einzige Datei
ls > all_files
Teilen Sie die Datei in Stapel auf
split -l 4 all_files all_files-
Sie haben jetzt 4 Dateinamen in jeder Datei,
all_files-*
Wählen Sie eine aus, sagen Sie
all_files-aa
und machen Sie Ihre Kopie:xargs -I{} cp {} folder_for_batch_1 < all_files-aa
quelle
ls | xargs -iX -n20 cp X target_folder/
würde cp auf Dateien in Stapeln von 20 ausführen, bis sie alle fertig waren.