루프에서 mv를 사용하여 이름이 다른 여러 아카이브를 어떻게 이동할 수 있습니까?

루프에서 mv를 사용하여 이름이 다른 여러 아카이브를 어떻게 이동할 수 있습니까?

L의 범위는 1에서 10이고 K의 범위는 0.00에서 49.80인 LposK.dat라는 이름의 2500개 아카이브가 있습니다. 동일한 K를 가진 항목을 폴더로 이동해야 합니다. 나는 다음을 사용하여 이 작업을 수행합니다.

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

하지만 수동으로 K 값을 변경하고 이를 여러 번 반복해야 합니다. find 및 mv 명령 내에서 루프(예: for 루프)의 인덱스를 사용하여 스크립트를 작성할 수 있는 방법이 있는지 궁금합니다.

답변1

Kfrom 을 얻으려면 LposK.dat해당 문자열이 in 에 있으면 $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/pathposfind

하나의 파일을 이동하려면:

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

관련 정보