
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/path
pos
find
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