Einzelbefehlslösungen
Unter vielen Optionen, einschließlich Schleifen, die cp
und verwenden sleep
, könnten wir uns für find
zwei -exec
Flags entscheiden, um genau diese Befehle auszuführen.
find ~/dir_1/ -type f -maxdepth 1 -exec cp {} ~/dir_2 \; -exec sleep 1 \;
Hier sind die Optionen:
~/dir_1
, das Ursprungsverzeichnis, über das find
funktioniert.
-type f
Holen Sie sich nur Dateien
-maxdepth 1
im Verzeichnisbaum maximal 1 Ebene nach unten absteigen; verhindert das Absteigen in Unterverzeichnisse
-exec cp {} ~/dir_2 \;
Kopieren Sie die aktuell verarbeitete Datei, die durch den {}
Parameter festgelegt wurde, nach ~/dir_2
. Das \;
bezeichnet cp
die Verarbeitung einer einzelnen Datei gleichzeitig, anstatt so viele Dateien wie möglich in die Datei zu stecken {}
. Der Backslash-In \;
ist erforderlich, um zu verhindern, dass die Shell diesen als Befehlsabschluss falsch interpretiert.
exec sleep 1 \;
wird für sleep 1
jede aktuelle Datei ausgeführt.
Wenn Sie eine Liste von Dateien in einer Datei haben, können Sie Folgendes tun:
xargs -I % --arg-file=input.txt sh -c 'cp % ~/dir_2/ ;sleep 1'
Optionen hier sind:
-I %
bezeichnet das Symbol, das sich auf die Datei innerhalb des Befehls bezieht
--arg-file=input.txt
Lesen Sie die zu befehlenden Argumente aus einer bestimmten Datei
sh -c 'cp % ~/dir_2/ ;sleep 1'
/bin/sh
mit bereitgestellten Befehlen per -c '...'
Flag ausführen ; %
wird durch Dateinamen ersetzt.
Schleifenlösungen
Sie könnten zum Beispiel eine for-Schleife verwenden
for f in "/path/to/folder_1"/*; do
cp "$f" "/path/to/folder_2/"
sleep 1
done
Aus Gründen der Übersichtlichkeit ist dies in mehreren Zeilen formatiert, dies funktioniert jedoch genauso gut als einzelne Zeile. Sie können dies auch in eine Funktion verwandeln:
delaycp(){
for f in "$1"/*; do
cp "$f" "$2"/
sleep 1
done
}
Und benutze es als
delaycp "/path/to/folder1" "/path/to/folder2"
Wenn Sie alternativ nur bestimmte Dateien kopieren möchten, nicht alles, was *
Glob im Verzeichnis erfasst, können Sie auch die Pfadnamenerweiterung verwenden, etwa eine file{1..25}
oder eine Eingabetextdatei wie diese input.txt
:
/path/to/folder_1/file1
/path/to/folder_1/file2
/path/to/folder_1/file3
Und von dort aus nutzen Sie die while IFS= read -r line
Struktur, um die Datei zu lesen:
while IFS= read -r line || [ -n "$line" ]; do
cp "$line" "/path/to/folder_2/${line##*/}"
sleep 1
done < input.txt
while
Schleife tun?\n
Newline endet. Erstellen Sie diese Datei als Beispiel :printf "Line one\nLine two" > input.txt
. Die while-Schleife ohne diese oder Klausel wird nur erhaltenLine one
. Warum ? Weil "read" eingebaut nur dann Erfolg bringt, wenn die Zeile mit endet\n
. DasLine two
wird immer noch in derline
Variablen landen , aberread
den Fail-Exit-Status zurückgeben. Deshalb brauchen wir eine zusätzliche Prüfung, falls die Variable nicht leer ist.find
Lösung sollte das erste Argument~/dir_1
anstelle von sein~/dir_2
. Der ganze Befehl ist korrekt, nur die Erklärung nicht.Mit
parallel
Hier ist eine
parallel
Lösung, geben Sie die Argumenteparallel
mit:::
genau wie mitcp
oder verwenden Sie eine Dateiliste:Die
-j
Option weistparallel
an, dass nur1
Jobs gleichzeitig ausgeführt werden sollen, anstatt Jobs parallel auszuführen. Die einfachen Anführungszeichen enthalten lediglich das Skript, in dem{}
die aktuell verarbeitete Datei ersetzt wird, und /:::
oder::::
führen die Argumentliste bzw. die Argumentdatei (en) ein. Sehen Sieman parallel
für viel mehr.Mit
find -exec
find
bietet eine bequeme Möglichkeit, Befehle für die Ergebnisse auszuführen, z. B. um jede.log
Datei in und unter das aktuelle Verzeichnis zu kopieren.quelle