我是一名 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]/