美好的一天,
我需要将786个文件夹移动到另一个位置,每个文件夹中至少有一个文件。这些文件夹中的大多数在我需要它们移动的位置具有相同的命名文件夹,并且它们内部具有相同的命名文件。例如,必须移动文件夹33。文件夹层次结构如下所示:/ 33 / 1.TIF。在我需要的位置,要移动的文件夹是同一个文件夹,其中包含相同的命名文件。如果我尝试将此文件夹移动到那里,它们将相互冲突。所以我需要回避它。
我有一个CSV文件,其中包含旧文件夹名称和新名称。我是linux和shell的新手,所以我真的不知道从哪里开始。
答案 0 :(得分:0)
有很多方法可以合并目录。难点在于检查目标目录中是否已存在具有相同名称的文件,然后递增源文件的名称以避免覆盖目标< / em>的
根据#.TIF
的命名约定,一种方法是扫描目标目录中的文件并确定max #
。您还需要扫描源文件以解决目标中源文件尚不存在的情况。
您拥有max #
文件集,只需循环遍历每个文件,检查它是否已存在,如果是,请将文件从当前#
移至{{1}在目标目录中。如果文件尚未存在,只需移动它即可。这同样适用于目标目录结构中尚不存在的源目录 - 只需移动它即可。
将所有部分组合在一起,您可以执行类似于以下操作的内容,其中脚本将# + max
目录名称,old
目录名称和new
作为参数(默认{{ 1}}):
ext
例如,如果您有以下旧目录结构和新目录结构:
TIF
该脚本将产生以下结果(您可以删除#!/bin/bash
[ -z "$1" -o -z "$2" ] && { ## validate 2 arguments given
printf "error: insufficient input, usage: %s old new\n" "${0##*/}"
exit 1
}
old="$1" ## assign arguments to 'old' and 'new' (readability)
new="$2"
ext="${3:-TIF}"
[ -d "$old" -a -d "$new" ] || { ## validate both old/new are directories
printf "error: invalid input.\n"
[ -d "$old" ] || printf " '%s' is not a directory.\n" "$old"
[ -d "$new" ] || printf " '%s' is not a directory.\n" "$new"
exit 1
}
while read -r dname; do ## for each old directory
max=0 ## zero max
nname="${dname/$old/$new}" ## generate new dir name
if [ -d "$nname" ]; then ## check if new dir exists, if so
## get max file # in old & new
for i in "$dname"/*; do ## for each file in old
[ -f "$i" ] || continue ## skip if not file
fn="${i%.$ext}" ## get the number
fn=${fn#${dname}/}
((fn > max)) && max=$fn ## update max if greater
done
for i in "$nname"/*; do ## do the same for new dir
[ -f "$i" ] || continue
fn="${i%.$ext}"
fn=${fn#${nname}/}
((fn > max)) && max=$fn
done
## move files from old to new
for i in "$dname"/*; do ## for each file in old
[ -f "$i" ] || continue
newfn="${i/$old/$new}" ## form new file name
if [ -f "$newfn" ]; then ## check if it exists, if so
fn="${i%.$ext}"
fn=${fn#${dname}/} ## add max to number and mv
printf "mv %s %s\n" "$i" "${newfn%/*}/$((fn + max)).$ext"
mv "$i" "${newfn%/*}/$((fn + max)).$ext"
else ## otherwise, just mv
printf "mv %s %s\n" "$i" "$newfn"
mv "$i" "$newfn"
fi
done
else ## if no new dir exists, move old new
printf "mv %s %s\n" "$dname" "$nname"
mv "$dname" "$nname"
fi
done < <(find "$old" -type d)
语句,或将输出重定向到$ tree old
old
├── 22
│ ├── 1.TIF
│ ├── 2.TIF
│ ├── 3.TIF
│ └── 4.TIF
├── 23
│ ├── 1.TIF
│ ├── 2.TIF
│ ├── 3.TIF
│ ├── 4.TIF
│ └── 5.TIF
└── 24
├── 1.TIF
└── 2.TIF
$ tree new
new
├── 22
│ ├── 1.TIF
│ ├── 2.TIF
│ └── 3.TIF
└── 23
├── 1.TIF
├── 2.TIF
└── 3.TIF
以禁止显示文本)
printf
现在/dev/null
目录树包含以下内容:
$ bash mvoldnew.sh old new
mv old/24 new/24
mv old/22/1.TIF new/22/5.TIF
mv old/22/2.TIF new/22/6.TIF
mv old/22/3.TIF new/22/7.TIF
mv old/22/4.TIF new/22/4.TIF
mv old/23/1.TIF new/23/6.TIF
mv old/23/2.TIF new/23/7.TIF
mv old/23/3.TIF new/23/8.TIF
mv old/23/4.TIF new/23/4.TIF
mv old/23/5.TIF new/23/5.TIF
仔细看看并告诉我您是否有任何问题,或者我是否误解了您的澄清。