データの確認やファイル削除のための「cp」のような命令はありますか?

データの確認やファイル削除のための「cp」のような命令はありますか?

私の携帯電話に写真ファイルがいくつかあり、外付けドライブにバックアップしています。 (すべてはLinuxノートブックにインストールされます。)

ファイルをコピーしましたが、必ずmv

ところでこれで作業を行ったので、各ファイルごとにコピーされたデータが正しいことを確認し、エラーなくファイルがコピーされたら携帯電話からそのファイルを削除したいと思います。

だから私が本当に探しているのは、次cpのコマンドですmv

  • ターゲットにファイルがない場合は、ファイルをコピーしてください。
  • ソースとターゲットの間のデータを確認する(コピー後にファイルがまだない場合)
  • 両方のファイルのバイナリが同じ場合は、ソースからそのファイルを削除します。

私はこれを行うことができると思いましたが、rsync削除に似たさまざまなオプションを見ましたが、「削除」では何も見つけることができませんでした。源泉代わりに、このオプションは(?)前/後/中からファイルを削除します。目的地代わりに。

答え1

(注:rsync --remove-source-filesこれはデータを検証しないことを除いて、私が探しているコマンドです。)

diffバイナリ比較に関しては、次のことができることがわかりました。

ソースディレクトリから:

for f in *.jpg; do diff $f "/path/to/destination/$f"; done

ソースとターゲットのバイナリを比較します。出力なし = ファイルに違いはありません。

これは、データを検証するために使用できます。

diff違いが見つからずに返されるので動作します。0

for f in *.jpg; do diff $f "/desination/$f" && rm $f; done

返されると、$fソースフォルダのファイルが削除されます。つまり、ファイルは同じバイナリです。diff0

新しいコマンドのように見せると便利ですverify-rm。これをと呼びます。

ドロップボックスがインストールされているので、6ヶ月後にOSを再インストールするときにバックアップの心配がないように、スクリプトをドロップボックスフォルダに入れます。

$ cd ~/Dropbox && mkdir my-scripts && cd my-scripts
$ vim verify-rm

これは私のverify-rmスクリプトです。

if [ "$#" -lt 2 ];
then
    echo "Bad arguments, use like cp command"
else
    success=0
    fail=0
    error=0
    for arg in ${@:1:$(($#-1))}
    do
        #echo "$arg ${@:(-1):1}"
        diff "$arg" "${@:(-1):1}"
        ret=$?
        if [ $ret -eq 0 ]
        then
            success=$((success+1))
            echo "Verified file $arg"
            rm $arg
        elif [ $ret -eq 1 ]
        then
            fail=$((fail+1))
            echo "Binary files $arg and ${@:(-1):1} differ"
        else
            error=$((error+1))
            echo "diff exited with error: code=$ret"
        fi
    done
    echo "Summary: $success files verified and ok"
    echo "         $fail files differ!"
    echo "         $error errors"
    echo "Files which differ not removed"
    echo "Files where diff returned error code not removed"
fi

スクリプトを実行可能にする

$ chmod +x verify-rm

次に、新しいスクリプト(「コマンド」)を使用します。

$ verify-rm /path/to/source/*.jpg /path/to/destination

ファイル名にスペースが含まれているファイルは、bashがスペース間の各文字セットを異なる引数として扱うため、正しく処理されないことがわかりました。何をすべきか、修正できるかどうかはわかりません。

rsync --remove-source-filesしかし、コメントはファイル名に空白があってもうまくいき、うまく機能すると言われており、rsync速度もはるかに高速であることがわかったので、単に使用することをお勧めしますrsync

答え2

私のコメントに言及しましたが、rsync --remove-source-filesスクリプトの答えをさらに一歩進めたい場合は、次のヒントをいくつか参照してください。

2つのファイル(バイナリファイルを含む)に対してブール比較を実行したい場合は、標準よりもいくつかの優れた方法がありますdiff。 1つは、cmp2つのファイルをバイト単位で比較することです。あるいは、チェックサムを以下と比較することもできます。

diff -q <(cksum file1) <(cksum file2)

ファイル名の空白に関して、これはいくつかの解決策があるよく知られている問題です。以下は非常に包括的な要約です。https://www.dwheeler.com/essays/filenames-in-shell.html。スクリプトを共有する予定がない場合は、最適な選択肢を選択してください。

答え3

rsync --remove-source-filesあなたのためにこの正確な使命を果たします。 (しかし、私が何をすべきかわからなかったことの1つは、ターゲットファイルがすでに存在し、一致する場合はソースファイルを削除することです。)

ファイルを検証しないという印象を受けましたが、マンページ:

rsync は、ファイルの転送時に生成されたファイルの全チェックサムをチェックし、送信された各ファイルが受信側で正しく再構成されていることを常に確認しますが、自動転送後の確認はこのオプションとは無関係です。 the-transfer "このファイルを更新する必要がありますか?"ビュー。

関連情報