Как можно переместить несколько архивов с разными именами, используя mv в цикле?

Как можно переместить несколько архивов с разными именами, используя mv в цикле?

У меня есть 2500 архивов с именем LposK.dat, где L находится в диапазоне от 1 до 10, а K — в диапазоне от 0,00 до 49,80. Мне нужно переместить те, у которых K одинаков, в папку. Мне удается сделать это с помощью:

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

Но мне нужно вручную изменить значение K и повторить это несколько раз. Мне было интересно, есть ли способ использовать индекс цикла (например, for loop) внутри команд find и mv, чтобы я мог написать скрипт для этого.

решение1

Чтобы получить Kиз LposK.dat, если эта строка находится в $name, мы можем сделать

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

Это сработало бы, даже если бы $nameбыло имя пути вроде some/path/LposK.dat(и даже если бы some/pathсодержало строку pos), что полезно, когда мы позже вставим его в find.

Чтобы переместить один файл:

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

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

С 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 {} +

Это даст внутреннему sh -cскрипту несколько путей в качестве аргументов, и скрипт будет перебирать их, перемещая каждый из них в нужный подкаталог $HOME/destination.

Связанный:


Если ваши файлы находятся в одном подкаталоге (текущем каталоге), то вы можете сделать это еще проще без 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

Связанный контент