Wie kann ich mehrere Archive mit unterschiedlichen Namen mit mv in einer Schleife verschieben?

Wie kann ich mehrere Archive mit unterschiedlichen Namen mit mv in einer Schleife verschieben?

Ich habe 2500 Archive mit dem Namen LposK.dat, wobei L zwischen 1 und 10 und K zwischen 0,00 und 49,80 liegt. Ich muss die Archive mit dem gleichen K in einen Ordner verschieben. Das gelingt mir mit:

find . -name '*posK.dat' -exec mv {} ~/destination/K \;

Aber ich muss den Wert von K manuell ändern und dies mehrmals wiederholen. Ich habe mich gefragt, ob es eine Möglichkeit gibt, den Index einer Schleife (z. B.: for-Schleife) in den Befehlen find und mv zu verwenden, damit ich ein Skript dafür schreiben kann.

Antwort1

Um das Kvon zu erhalten LposK.dat, wenn die Zeichenfolge in ist $name, können wir Folgendes tun

k=${name%.dat}  # remove ".dat" suffix
k=${k##*pos}    # remove everything up to end of (the last) "pos"

Dies würde auch funktionieren, wenn $namees sich um einen Pfadnamen wie handelt some/path/LposK.dat(und selbst wenn some/pathdie Zeichenfolge enthalten wäre pos), was nützlich ist, wenn wir es später in einfügen find.

So verschieben Sie eine Datei:

k=${name%.dat}
k=${k##*pos}

dest="$HOME/destination/$k"
mkdir -p "$dest" && mv "$name" "$dest"  # only move if mkdir did not fail

Mit find:

find . -type f -name '*pos*.dat' -exec sh -c '
    for name do
        k=${name%.dat}
        k=${k##*pos}

        dest="$HOME/destination/$k"
        mkdir -p "$dest" && mv "$name" "$dest"
    done' sh {} +

Dadurch erhält das interne sh -cSkript eine Reihe von Pfadnamen als Argumente und das Skript iteriert über diese und verschiebt jeden in das richtige Unterverzeichnis von $HOME/destination.

Verwandt:


Wenn sich Ihre Dateien in einem einzigen Unterverzeichnis (dem aktuellen Verzeichnis) befinden, können Sie dies noch einfacher tun, ohne find:

for name in ./*pos*.dat; do
    [ ! -f "$name" ] && continue  # skip non-regular files

    k=${name%.dat}
    k=${k##*pos}

    dest="$HOME/destination/$k"
    mkdir -p "$dest" && mv "$name" "$dest"
done

verwandte Informationen