2017-07-06 129 views
0

我有一个目录,其中有数以千计的文件,其中有各种扩展名。我也有一个放置位置,用户放置要迁移到此目录的文件。我正在寻找一个脚本,它将扫描目标目录中的重复文件名,如果找到,请将该文件重命名为drop文件夹,然后将其移至目标目录。 实施例:bash - 在目录中找到重复的文件并重命名

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

脚本将重命名FILE.DOC到的File1.doc然后将其移动到/目标/。 它也需要维护文件扩展名。

+0

您确定要说什么:*扫描目标目录以找到重复的文件名,如果找到了,请将该文件重命名为drop文件夹,然后将其移至目标目录。*因此**您是什么意思重复**?你的意思是重复**名**或**存在**。添加更准确的示例 –

回答

2
for fil in /drop/* 
do 
    test -f "/target/$fil" 
    if [ "$?" = 0 ] 
    then 
     suff=$(awk -F\. '{ print "."$NF }' <<<$fil) 
     bdot=$(basename -s $suff $fil) 
     mv "/drop/$fil" "/drop/${bdot}1$suff" 
     cp "/drop/${bdot}1.$suff" "/target/${bdot}1$suff" 
    fi 
done 

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

+0

这不会保留扩展名 –

+0

非常正确@Kip K.我修改了扩展名, –

-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/
+1

非常感谢!这正是我所期待的。 –

1

你必须采取更多的照顾比,如果一个文件,以提供灵活的解决方案,可以处理文件移动之前存在就是检查有或没有扩展名。您也可能想要提供一种形成保存排序顺序的重复文件名的方法。例如如果file.txt已经存在,则您可能希望使用file_001.txt作为target中的副本,而不是file1.txt,因为当您达到10时,将不再有按文件名进行规范排序。

此外,你永远不想迭代for i in $(ls dir),这是陷阱。见Bash Pitfalls No. 1

把这些拼在一起,并且包括详细的评论下面,你可以做类似下面的内容,并有一个合理的灵活的解决方案,让您只指定filename.ext移动或/path/to/drop/filename.ext。您必须在脚本中指定droptarget目录以符合您的情况。

#!/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 
+0

请勿使用'-o';它是非标准的,并且都被弃用。使用'test -w“$ 1”||测试-w“$ drp/$ 1”'代替。 – chepner

+0

旧习惯....会修改。 –