我有一个目录,其中包含数千个带有各种扩展名的文件。我还有一个放置位置,用户放置要迁移到此目录的文件。我正在寻找一个脚本,它将扫描目标目录中的重复文件名,如果找到,则重命名drop文件夹中的文件,然后将其移动到目标目录。 例如:
/target/file.doc /drop/file.doc
脚本会将file.doc重命名为file1.doc,然后将其移至/ target /。 它也需要维护文件扩展名。
答案 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.ext
或drop
。您必须在脚本中指定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 /