bash - 在目录中找到重复文件并重命名

时间:2017-07-06 14:17:43

标签: bash

我有一个目录,其中包含数千个带有各种扩展名的文件。我还有一个放置位置,用户放置要迁移到此目录的文件。我正在寻找一个脚本,它将扫描目标目录中的重复文件名,如果找到,则重命名drop文件夹中的文件,然后将其移动到目标目录。 例如:

/target/file.doc /drop/file.doc

脚本会将file.doc重命名为file1.doc,然后将其移至/ target /。 它也需要维护文件扩展名。

3 个答案:

答案 0 :(得分:2)

App_Start

将每个文件放在drop目录中,并使用test -e检查它是否存在/ target。如果是,则移动(重命名)然后复制。

答案 1 :(得分:1)

为了提供可以处理带或不带扩展名的文件的灵活解决方案,您必须更加小心,而不仅仅是在移动之前检查文件是否存在。您还可能希望提供一种形成保留排序顺序的重复文件名的方法。例如如果file.txt已经存在,您可能希望将file_001.txt用作target中的副本,而不是file1.txt,因为当您到达10时,您将不再拥有for i in $(ls dir)按文件名排序。

此外,你永远不想与陷入困境的filename.ext进行迭代。见Bash Pitfalls No. 1

将这些内容放在一起,并在下面的评论中包含详细信息,您可以执行与以下内容类似的操作,并提供合理灵活的解决方案,以便仅指定要移动的/path/to/drop/filename.extdrop。您必须在脚本中指定target#!/bin/bash tgt=target ## set target and drop directories as required drp=drop declare -i cnt=1 ## counter for filename_$cnt test -z "$1" && { ## validate one argument given printf "error: insufficient input\nusage: %s filename\n" "${0##*/}" exit 1 } test -w "$1" || test -w "$drp/$1" || { ## validate valid filename is writeable printf "error: file not found or lack permission to move '%s'.\n" "$1" exit 1 } fn="${1##*/}" ## strip any path info from filename if test "$1" != "${1%.*}" ; then ext="${fn##*.}" ## get file extension fnwoe="${fn%."$ext"}" ## get filename without extension test "$fnwoe" = '' && ext= ## was a dotfile, reset ext fi vfn="$fn" ## set valid filename = filename ## form valid filename e.g. "$fn_001.$ext" if duplicate found while test -e "$tgt/$vfn"; do if test -n "$ext" ## did we have have an extension? then printf -v vfn "%s_%03d.%s" "$fnwoe" "$((cnt++))" "$ext" else printf -v vfn "%s_%03d" "$fn" "$((cnt++))" fi done mv "$drp/$fn" "$tgt/$vfn" ## move file under non-conflicting name 目录以满足您的使用情况。例如

$ ls -1 drop
file
file.txt

$ ls -1 target
file.txt
file_001.txt
file_002.txt

示例丢弃和目标

$ bash mvdrop.sh file
$ bash mvdrop.sh drop/file.txt

使用示例

$ ls -1 drop

$ ls -1 target
file
file.txt
file_001.txt
file_002.txt
file_003.txt

产生的下降和目标

{{1}}

答案 2 :(得分:-1)

这将测试它是否存在,保留扩展名(以及扩展名之前的任何结构,例如FILE.tar.gz),并将其移动到目标目录。

#!/bin/bash

TARGET="\target\"
DROP="\drop\"

for F in `ls $DROP`; do
    if [[ -f $TARGET$F ]]; then
        EXT=`echo $F | awk -F "." '{print $NF}'`
        PRE=`echo $F | awk -F "." '{$NF="";print $0}' | sed -e 's/ $//g;s/ /./g'`
        mv $DROP$F $DROP$PRE"1".$EXT
        F=$PRE"1".$EXT
    fi
    mv $DROP$F $TARGET
done

此外,您可能希望限制ls命令,以便不复制整个目录。

仅显示常规文件(无目录或符号链接)

ls -p $DROP | grep -v /