私はRユーザーで、まだUnixやコマンドラインコーディングに慣れていません。ファイルを含むサブフォルダがあるディレクトリがあり、ファイル名はすべて同じですが、サブフォルダはない他のディレクトリがあります(ただし、内容が変更されたため、そのディレクトリを使用する必要があります)。古いディレクトリのファイル名と構造を一致させて新しいディレクトリにサブフォルダを作成するには?すべての新しいファイルにフォルダ名を追加できるようにしたいです。組織の元のディレクトリにあるファイル名にフォルダ名を追加してから、古いファイル名の一部を一致させて新しいファイル名を更新する方が簡単な場合は、問題ありません。
答え1
前のデータファイルのフルパスが次の場所にあるとしますdir1
。
$ ls -l dir1/*/*
-rw------- 1 jim wheel 0 Apr 13 10:24 dir1/A/file_1
-rw------- 1 jim wheel 0 Apr 13 10:24 dir1/A/file_2
-rw------- 1 jim wheel 0 Apr 13 10:24 dir1/A/file_3
-rw------- 1 jim wheel 0 Apr 13 10:24 dir1/B/file_4
-rw------- 1 jim wheel 0 Apr 13 10:24 dir1/B/file_5
-rw------- 1 jim wheel 0 Apr 13 10:24 dir1/B/file_6
-rw------- 1 jim wheel 0 Apr 13 10:24 dir1/C/file_7
-rw------- 1 jim wheel 0 Apr 13 10:24 dir1/C/file_8
-rw------- 1 jim wheel 0 Apr 13 10:24 dir1/C/file_9
-rw------- 1 jim wheel 0 Apr 13 10:55 dir1/D/file_1
-rw------- 1 jim wheel 0 Apr 13 10:55 dir1/D/file_2
-rw------- 1 jim wheel 0 Apr 13 10:55 dir1/D/file_3
-rw------- 1 jim wheel 0 Apr 13 10:55 dir1/D/file_4
-rw------- 1 jim wheel 0 Apr 13 10:55 dir1/D/file_5
-rw------- 1 jim wheel 0 Apr 13 10:55 dir1/D/file_6
-rw------- 1 jim wheel 0 Apr 13 10:55 dir1/D/file_7
-rw------- 1 jim wheel 0 Apr 13 10:55 dir1/D/file_8
-rw------- 1 jim wheel 0 Apr 13 10:55 dir1/D/file_9
パスのない新しいデータファイルは、次の場所にありますdir2
。
$ ls -l dir2/*
-rw------- 1 jim wheel 29 Apr 13 10:24 dir2/file_1
-rw------- 1 jim wheel 0 Apr 13 10:57 dir2/file_10
-rw------- 1 jim wheel 29 Apr 13 10:24 dir2/file_2
-rw------- 1 jim wheel 29 Apr 13 10:24 dir2/file_3
-rw------- 1 jim wheel 29 Apr 13 10:24 dir2/file_4
-rw------- 1 jim wheel 29 Apr 13 10:24 dir2/file_5
-rw------- 1 jim wheel 29 Apr 13 10:24 dir2/file_6
-rw------- 1 jim wheel 29 Apr 13 10:24 dir2/file_7
-rw------- 1 jim wheel 29 Apr 13 10:24 dir2/file_8
-rw------- 1 jim wheel 29 Apr 13 10:24 dir2/file_9
スクリプトを生成する場合test.sh
:
$ cat << EOF > test.sh
#!/usr/bin/env bash
# pathA has sub-dir paths to files which contain old data:
pathA="dir1"
# pathB has only files (no sub-dirs) which contain new data:
pathB="dir2"
# We will create pathC to contain paths to sub-directories with
# files containing new data:
pathC="dir3"
# First, remove pathC and rsync pathA into it:
rm -rf "$pathC"
rsync -a "$pathA/" "$pathC/"
# Now, for each file in pathB:
for f in $(find "$pathB" -type f)
do
# ... find all the files matching that name in pathC
readarray -t af < <(find "$pathC" -type f -name "$(basename "$f")")
# ... copy file f to each location l in pathC
for l in "${af[@]}"
do
cp -vp "$f" "$l"
done
done
EOF
変数を編集し、パスとともに古いデータファイルの場所にtest.sh
設定します。pathA
変数をpathB
パスなしで新しいデータファイルの場所に設定します。pathC
作成したい新しいパスに変数を設定します。このディレクトリはすでに存在してはいけません。実際にスクリプトが実行されるたびに削除され、再生成されます。
スクリプトを実行可能にします。
$ chmod 755 test.sh
スクリプトを実行すると、dir3
新しいデータファイルを含む新しいディレクトリが作成され、次の構造に一致するサブディレクトリに配置されますdir1
。
$ ./test.sh
dir2/file_7 -> dir3/C/file_7
dir2/file_7 -> dir3/D/file_7
dir2/file_4 -> dir3/B/file_4
dir2/file_4 -> dir3/D/file_4
dir2/file_9 -> dir3/C/file_9
dir2/file_9 -> dir3/D/file_9
dir2/file_3 -> dir3/A/file_3
dir2/file_3 -> dir3/D/file_3
dir2/file_1 -> dir3/A/file_1
dir2/file_1 -> dir3/D/file_1
dir2/file_6 -> dir3/B/file_6
dir2/file_6 -> dir3/D/file_6
dir2/file_2 -> dir3/A/file_2
dir2/file_2 -> dir3/D/file_2
dir2/file_8 -> dir3/C/file_8
dir2/file_8 -> dir3/D/file_8
dir2/file_5 -> dir3/B/file_5
dir2/file_5 -> dir3/D/file_5
完了したときにすべてが良く見える場合は、名前をdir2
バックアップに変更してから、次にdir3
変更しますdir2
。
mv dir2 dir2.OLD && mv dir3 dir2
答え2
そしてzsh
:
#! /bin/zsh -
old_dir=${1?}
new_dir=${2?}
# build a filename -> subdir map
typeset -A map
for file ( $old_dir/*/**/*(N.) ) map[$file:t]=${${file#$old_dir/}:h}
# Process files in new dir:
for file ( $new_dir/*(N.) ) if (( $+map[$file:t] ))
mkdir -p -- $newdir/$map[$file:t] && mv -- $file $newdir/$map[$file:t]/