2017-07-06 18 views
0

私は、さまざまな拡張子を持つ数千のファイルがあるディレクトリを持っています。また、ユーザーがこのディレクトリに移行するファイルをドロップするドロップ先もあります。私は、重複したファイル名が見つかった場合、ターゲットディレクトリをスキャンするスクリプトを探しています。ドロップフォルダ内のファイルの名前を変更し、それをターゲットディレクトリに移動します。 例:bash - ディレクトリに重複したファイルを見つけて名前を変更

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

スクリプトは、file1.docにfile.docの名前を変更/ターゲット/に移動します。 ファイルの拡張子も維持する必要があります。

+0

あなたが言ったことは確かですか?重複したファイル名がある場合はそのファイルを探し、ドロップ先のフォルダにファイル名を変更してから、目的のディレクトリに移動してください。重複**?あなたは** name **または** exist **の中に重複を意味します。より正確な例を追加 –

答えて

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

かなり右@キップ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が既に存在する場合、10になると、file1.txtではなく、targetではfile_001.txtを重複して使用することができます。ファイル名で正規の並べ替えができなくなります。

また、落とし穴で加工されたfor i in $(ls dir)で繰り返すことは決してありません。あなたは次のような何かをすると、あなただけ移動するfilename.extまたは/path/to/drop/filename.extを指定することができ、合理的な柔軟なソリューションを持っている可能性があり、Bash Pitfalls No. 1

が一緒にそれらの作品を置くと、以下のコメントで詳細を含めて参照してください。状況に応じて、スクリプトに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 "を使う|| test -w "$ drp/$ 1" 'を実行してください。 – chepner

+0

古い習慣は....修正されます。 –

関連する問題