web-dev-qa-db-ja.com

ファイルの移動とファイルが宛先フォルダーに存在する場合の名前の変更

私はこれを Hazel で行っていました。ファイル拡張子に基づいて、すべてを~/Downloads/から~/Downloads/Archive/Pictures~/Downloads/Archive/Documents~/Downloads/Archive/Videosなどに移動します。同じ名前のファイルが既に存在する場合、Hazelは移動するファイルに番号を追加するだけです。

これを実現するシェルスクリプトを書きたかったのですが、ユーザー入力なしでファイルの名前を変更する方法がわからないことにすぐに気付きました。名前を変更するスキームは、ファイル名の後の単純なカウンターである可能性があり、mvが既存のファイルを上書きする場合にのみ実行する必要があります。また、同じファイル名のインスタンスがすでに多数存在する場合は、カウンターを続行できるはずです。したがって、すでにdirA/file.extdirB/が含まれているfile.extfile2.extに移動する場合、スクリプトは3からカウントを開始し、dirA/file.extの名前をdirB/file3.extに変更する必要があります。

誰かがこれを達成する方法について何かガイダンスを提供できますか?できればシェルスクリプトを使用しますが、そうでない場合は、Ruby、Perl、またはPythonのいずれかを使用します。これがシェルスクリプトでも可能かどうかを知るだけで役に立ちます。

5
Jukka Haav

それほど難しいことではありません。宛先ファイルが存在する場合は、ファイルをベース名と拡張子に分割し、新しいファイル名がターゲットディレクトリに存在しなくなるまでカウンターをインクリメントする必要があります。

source=dirA/file.ext
dest_dir=dirB

file=$(basename file.ext)
basename=${file%.*}
ext=${file##*.}

if [[ ! -e "$dest_dir/$basename.$ext" ]]; then
    # file does not exist in the destination directory
    mv "$source" "$dest_dir"
else
    num=2
    while [[ -e "$dest_dir/$basename$num.$ext" ]]; do
        (( num++ ))
    done
    mv "$source" "$dest_dir/$basename$num.$ext" 
fi 
8
glenn jackman

各ワークステーションにGNUバージョンのmvがインストールされている場合は、1つのコマンドでそれを行うこともできます。MacOSXに付属のデフォルトは--backupスイッチをサポートしていません。 GNU Coreutils for Mac OS Xは、Macportsや他の多くの場所から入手できます。

次に、それはただの問題です:

mv --backup = numbered dirA/file.ext dirB /

結果のファイル名はfile.ext.~1~file.ext.~2~などになります。

enter image description here

3
John T

Glennのおかげで、空の拡張子をサポートし、宛先として直接ファイルを受け入れるように機能を書き直しました(通常のmvと同じように)

mv_no_override() {
    local dir file ext base num
    if [ -d "$2" ]; then
        dir=$2
        file=$(basename "$1")
    else
        dir=$(dirname "$2")
        file=$(basename "$2")
    fi
    ext="$(sed -r 's/.+(\..+)|.*/\1/' <<<"$file")"
    base="$(sed -r 's/(.+)\..+|(.*)/\1\2/' <<<"$file")"
    while [ -e "$dir/$base$num$ext" ]; do
        (( num++ ))
    done
    mv "$1" "$dir/$base$num$ext"
}
0
phil294