あるディレクトリのサブフォルダを同じファイルがクリーンアップされていない別のディレクトリに追加し、ファイルの前にフォルダ名を追加する方法

あるディレクトリのサブフォルダを同じファイルがクリーンアップされていない別のディレクトリに追加し、ファイルの前にフォルダ名を追加する方法

私は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]/

関連情報