コピーの取り消し(cp)コマンドアクション


14

ターミナルで以下のコマンドラインを使用して、ソースフォルダーから宛先フォルダーにファイルをコピーしました。

sudo cp From_SOURCE/* To_DESTINATION/

次に、このコマンドを元に戻します。


理解したかどうかわかりません。単にコピーを削除しますか?(sudo rmファイル)
ジェイコブVlijm 14

@JacobVlijmアクションを元に戻すのではなく、別のコマンドです。コピーしなかった場合、以前に提案されたコマンドを使用できます。そして、私はこのコマンドを使用して、コピーされた1000以上のファイルを削除するためにますます時間が必要ですか?
αғsнιη

@KasiyA-オプションはFrom_SOURCE/*、選択されたすべてのファイル名を検索し、それらから削除することTo_DESTINATION/です。これはbashで行うことができます-ここでの問題はcpコマンドが何かを上書きしたり、シンボリックリンクがコピーされたり、名前にスペースが含まれるファイルなどを含む可能性があります。完璧な「元に戻す」オプションは、多くのものを考慮する必要があります。
ウィルフ14

回答:


13

私がよく理解していれば、次のことが当てはまります。

  • (おそらく大量の)ファイルを既存のディレクトリにコピーしましたが、アクションを元に戻す必要があります。
  • 対象のディレクトリには他のファイルが多数含まれているため、そこに保持する必要があるため、ディレクトリからすべてのファイルを単純に削除することはできません。

以下のスクリプトは、元の(ソース)ディレクトリを検索し、それらのファイルをリストします。次に、ファイルをコピーしたディレクトリを検索し、リストされたファイルのみを削除します。それらはソースディレクトリに存在するためです。

try要素はすでに手動でいくつかのファイルを削除した可能性がある、またはそうでない場合は、ソースディレクトリからすべてのファイルを宛先にコピーされた場合、たとえば、エラーを防止するために添加されます。sudo特権が必要な場合は、「sudo」でスクリプトを実行するだけです(以下を参照)。

スクリプト

#!/usr/bin/env python

import os

source_dir = "/path/to/source" # the folder you copied the files from
target_folder = "/path/to/destination" # the folder you copied the files to

for root, dirs, files in os.walk(source_dir):
    for name in files:
        try:
            os.remove(target_folder+"/"+name)
        except FileNotFoundError:
            pass

使い方

  • 空のファイルにスクリプトを貼り付け、として保存しreverse.py
  • ソースおよびターゲットフォルダーの正しいパスを挿入し、
  • 便宜上、実行可能にします。
  • 次のコマンドで実行します:

    [sudo] /path/to/reverse.py
    

警告

あなたが達成する必要があるものをよく理解しているなら、最初にテストディレクトリで試してください!


ソースディレクトリが「フラット」の場合

ソースディレクトリにサブディレクトリがない場合、スクリプトはさらに簡単になります。

#!/usr/bin/env python

import os

source_dir = "/path/to/source" # the folder you copied the files from
target_folder = "/path/to/destination" # the folder you copied the files to

for file in os.listdir(source_dir):
    try:
        os.remove(target_folder+"/"+file)
    except FileNotFoundError:
        pass

注意

コピーアクションがコピー先の同様の名前のファイルを上書き(置換)した場合、ファイルは削除されますが、元のファイルは(もちろん)スクリプトによって戻されません。前提は、名前の衝突がないことです。


うまくいきます、ありがとう。私はそれを実行しsudo python3 reverse.pyます。あなたの答えを受け入れます。
αғsнιη

パーフェクト!素敵な質問をありがとう。これはおそらく私たち全員がいる状況を説明している:)
ジェイコブヴリム14

注:ソースのファイルが同じ名前であるために宛先のファイルを上書きした場合、単に元に戻すことはできず、このスクリプトは削除するだけです。ここでの仮定は、あなたがイニシャルをしたとき名前の衝突がなかったということですcp
thomasrutter 14

@neon_overload正しい、私の答えで編集した。
ジェイコブVlijm 14

これはには機能しませんcp -r。で変更os.removeしましたがprint、存在しないファイルの束を出力しています。私はそれがサブディレクトリが欠落していると仮定し、最後にファイルのみをリストします。
タイプウォー

7

TL; DR:

両方に存在するすべてのファイルsrcdestから削除することができdest、このように:

find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;

段階的な説明については、以下を参照してください。

問題を単純化する:

取り消したいコマンドが実際に何をしたかを理解するために、単純化することから始めます。

元に戻すコマンドは

sudo cp From_SOURCE/* To_DESTINATION/

元に戻す方法を理解するには、 sudoは、関係ありません。

私は、ディレクトリ名を使用しますsrcためFrom_SOURCEdestのためにTo_DESTINATION

今、私たちのコマンドは次のとおりです。

cp src/* dest/

srcファイルf1f2およびf3、およびディレクトリd1およびが含まれている場合d2、シェルはそのコマンドを次のように展開します。

cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/

-r-Rまたはなどのオプションがない-a場合、コマンドcpはディレクトリをコピーしません。
つまり、コマンドはそれらを除外し、それぞれのエラーを表示します:

$ cp src/f1 src/f2 src/f3 src/d1 src/d2 dest/
cp: omitting directory 'src/d1'
cp: omitting directory 'src/d2'

つまり、単純なファイルのみをコピーし、ディレクトリはコピーしません。 dest

削除するファイルの決定:

のファイルdestと同じ名前のファイルがあった可能性がありますsrc。この場合、ファイルは上書きされました(1)。遅すぎてごめんなさい。最新のバックアップからそれらを取り戻します。

そこにあるファイルに関しては、コピーされたファイルのみを削除したいです。これらのファイルは、同じ名前で同じ内容の両方のディレクトリに存在します。

したがって、これらのファイルを探します。

まず、私たち cdsrcそれが次なるため、findコマンドがはるかに簡単、とdestの絶対パスに変数を設定します。

$ cd src
$ destdir="$(readlink -f dest)"

次に、src内のすべてのファイルをリストします。

$ find . -maxdepth 1 -type f

そして、見つかったファイルごとに、 cmp、destに同じ内容のファイルがあるかどうかを確認ためします。

$ find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -print

ファイルを慎重に削除します。

これらのファイルは削除したいものです。しかし、確かに、最初にそれらを別のディレクトリに移動します-そして、それらを実行する前にコマンドを見てください:

$ toDelete=/tmp/toDelete ; mkdir -p "$toDelete"
$ find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec echo mv -n "$destdir/{}" "$toDelete"/ \;
mv -n /path/to/dest/./f1 /tmp/toDelete/`
mv -n /path/to/dest/./f2 /tmp/toDelete/`
mv -n /path/to/dest/./f3 /tmp/toDelete/`

いいね!これでecho、実際のmvコマンドを実行するために省略できます。

find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;

からdestコピーされたすべてのファイルは、からにコピーされますがsrc、実際には、およびにあり、、srcおよびになりdest/tmp/toDelete/最後に見てから削除できます。


注:
(1)cpエイリアスであるかどうかを確認しcp -iます。エイリアスであると、最初に確認することでファイルの上書きを防ぐことができます。


5

これは古いですが、純粋なbashの回答を投稿したかっただけです。

最初に、ファイルをコピーしたディレクトリに移動します。

cd dest

次に、lsソースディレクトリと出力をパイプしますrm

ls source | xargs rm


1
解析lsは通常悪い考えです。mywiki.wooledge.org/ParsingLs 私はあなたの投稿に反対票を投じませんが、注意する必要があります。
セルギーKolodyazhnyy 16
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.