2017-07-06 140 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

舊習慣....會修改。 –