10 Stimmen

Stapelweises Kopieren und Umbenennen mehrerer Dateien

Ich möchte alle Dateien aus einem Verzeichnis rekursiv kopieren und umbenennen.

Ich habe etwas Ähnliches:

/dir/subdir/file.aa
/dir/subdir/fileb.aa
/dir/filec.aa

und möchte, dass alle Dateien wie folgt kopiert werden:

/newdir/1.xx
/newdir/2.xx
/newdir/3.xx
/newdir/4.xx

.. /newdir/nn.xx

Wie kann ich dies in der Bash tun?

5voto

glglgl Punkte 84928
find -name "*.aa" | cat -n | while read n f; do
    cp "$f" newdir/"$n".xx
done

funktioniert mit (fast) jedem gültigen Dateinamen (mit Ausnahme von Zeilenumbrüchen, die ebenfalls zulässig sind).

Wenn Sie nicht auf die Shell beschränkt sind, könnte eine andere Lösung in Python sein

#!/usr/bin/env python

if __name__ == '__main__':
    import sys
    import os
    import shutil
    target = sys.argv[1]
    for num, source in enumerate(sys.argv[2:]):
        shutil.move(source, os.path.join(target, "%d.xx" % num))

die dann wie folgt aufgerufen werden könnte

<script name> newdir *.aa

3voto

ypnos Punkte 47895

Probier so etwas aus:

num=0
for i in `find -name "*.aa"`; do
    let num=num+1
    cp $i newdir/$lc.xx
done

0voto

liberias Punkte 235

Ich werde versuchen, diese Frage zu beantworten, aber das ist vielleicht nicht die optimale Lösung, da es viele Tools gibt, die dafür verwendet werden können.

Meine Art, dieses Problem zu lösen, wäre, eine Funktion zu schreiben und diese Funktion dann auf jede Datei in dem Verzeichnis/den Unterverzeichnissen anzuwenden. Unter der Annahme, dass Sie mehrere Kerne/Prozessoren haben und dass Ihre Funktion etwas CPU-lastigeres tun würde als nur das Umbenennen und Kopieren von Dateien, würden Sie die Aufgabe auch parallelisieren.

Das Bash-Skript würde wie folgt aussehen:

#! /bin/bash
n=1
CopyAndRename() {
   NEWNAME=$n.xx
   cp "$i" /newdir/$NEWNAME 
   n=$[$n+1]
}

IFS=$'\n'
LIST=`find /dir -type f`

for i in $LIST; do
   CopyAndRename $i
done

Dies sollte auch für Dateinamen mit Leerzeichen und anderen Sonderzeichen gelten. Zur Parallelisierung könnten Sie ein Programm prll verwenden und die for-Schleife durch

prll CopyAndRename $LIST

Für das Umbenennen und Kopieren ist dies jedoch nicht notwendig.

0voto

Ole Tange Punkte 29091

Mit GNU Parallel sieht das so aus:

 find ... | parallel cp {} /newdir/{#}.xx

Dies geschieht parallel (ein Auftrag pro Kern), was den Kopiervorgang je nach Speichersystem beschleunigen kann.

GNU Parallel ist ein allgemeiner Parallelisierer und macht es einfach, Aufträge parallel auf demselben Rechner oder auf mehreren Rechnern, auf die Sie per ssh Zugriff haben, auszuführen.

Wenn Sie 32 verschiedene Aufträge auf 4 CPUs ausführen wollen, ist eine einfache Möglichkeit der Parallelisierung, 8 Aufträge auf jeder CPU auszuführen:

Simple scheduling

GNU Parallel legt stattdessen einen neuen Prozess an, wenn ein Prozess beendet wird - so bleiben die CPUs aktiv und es wird Zeit gespart:

GNU Parallel scheduling

Einrichtung

Wenn GNU Parallel nicht für Ihre Distribution gepackt ist, können Sie eine persönliche Installation durchführen, die keinen Root-Zugriff erfordert. Die Installation kann in 10 Sekunden durchgeführt werden, indem Sie dies tun:

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 883c667e01eed62f975ad28b6d50e22a
12345678 883c667e 01eed62f 975ad28b 6d50e22a
$ md5sum install.sh | grep cc21b4c943fd03e93ae1ae49e28573c0
cc21b4c9 43fd03e9 3ae1ae49 e28573c0
$ sha512sum install.sh | grep da012ec113b49a54e705f86d51e784ebced224fdf
79945d9d 250b42a4 2067bb00 99da012e c113b49a 54e705f8 6d51e784 ebced224
fdff3f52 ca588d64 e75f6033 61bd543f d631f592 2f87ceb2 ab034149 6df84a35
$ bash install.sh

Für andere Installationsoptionen siehe http://git.savannah.gnu.org/cgit/parallel.git/tree/README

Mehr erfahren

Siehe weitere Beispiele: http://www.gnu.org/software/parallel/man.html

Sehen Sie sich die Einführungsvideos an: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Gehen Sie durch das Tutorial: http://www.gnu.org/software/parallel/parallel_tutorial.html

Tragen Sie sich in die E-Mail-Liste ein, um Unterstützung zu erhalten: https://lists.gnu.org/mailman/listinfo/parallel

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X