用于重命名文件夹和子文件的Shell脚本

时间:2016-07-22 12:31:12

标签: linux bash shell

美好的一天,

我需要将786个文件夹移动到另一个位置,每个文件夹中至少有一个文件。这些文件夹中的大多数在我需要它们移动的位置具有相同的命名文件夹,并且它们内部具有相同的命名文件。例如,必须移动文件夹33。文件夹层次结构如下所示:/ 33 / 1.TIF。在我需要的位置,要移动的文件夹是同一个文件夹,其中包含相同的命名文件。如果我尝试将此文件夹移动到那里,它们将相互冲突。所以我需要回避它。
我有一个CSV文件,其中包含旧文件夹名称和新名称。我是linux和shell的新手,所以我真的不知道从哪里开始。

1 个答案:

答案 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

仔细看看并告诉我您是否有任何问题,或者我是否误解了您的澄清。