ループ内で mv を使用して、異なる名前を持つ複数のアーカイブを移動するにはどうすればよいですか?

ループ内で mv を使用して、異なる名前を持つ複数のアーカイブを移動するにはどうすればよいですか?

LposK.dat という名前のアーカイブが 2500 個あります。L は 1 から 10、K は 0.00 から 49.80 です。同じ K を持つアーカイブをフォルダーに移動する必要があります。次の方法でこれを実現できます。

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

しかし、K の値を手動で変更し、それを複数回繰り返す必要があります。find コマンドと mv コマンド内でループのインデックス (例: for ループ) を使用して、それを実行するスクリプトを作成する方法はあるでしょうか。

答え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/pathposfind

1 つのファイルを移動するには:

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

関連情報