ターミナルで以下のコマンドラインを使用して、ソース フォルダーから宛先フォルダーにいくつかのファイルをコピーしました。
sudo cp From_SOURCE/* To_DESTINATION/
ここでこのコマンドを元に戻したいと思います。
答え1
私の理解が正しければ、次のようになります。
- 既存のディレクトリに(おそらく大量の)ファイルをコピーしましたが、その操作を元に戻す必要があります。
- 対象ディレクトリには、他の保存する必要があるファイルがあり、簡単に削除することはできません全てディレクトリからのファイル
以下のスクリプトは、元の (ソース) ディレクトリを調べて、それらのファイルを一覧表示します。次に、ファイルをコピーしたディレクトリを調べて、一覧表示されたファイルのみをソース ディレクトリ内に存在するものとして削除します。
この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
注記
コピーアクションの場合上書きした宛先に同様の名前のファイルがある場合 (置き換えられた場合)、そのファイルは削除されますが、元のファイルは (もちろん) スクリプトによって復元されません。名前の衝突がないことが前提となります。
答え2
要約:
両方に存在しsrc
、次のようdest
に削除できるすべてのファイルdest
:
find . -maxdepth 1 -type f -exec cmp -s '{}' "$destdir/{}" \; -exec mv -n "$destdir/{}" "$toDelete"/ \;
段階的な説明については、以下を参照してください。
問題を単純化すると:
元に戻したいコマンドが実際に何をしたかを理解するために、まずはそれを簡略化します。
元に戻したいコマンドは
sudo cp From_SOURCE/* To_DESTINATION/
元に戻す方法を理解することsudo
は関係ありません。
src
およびFrom_SOURCE
にdest
はディレクトリ名を使用しますTo_DESTINATION
。
さて、私たちの命令は次の通りです:
cp src/* dest/
src
にファイルf1
、f2
および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)。残念ながら、もう手遅れです。最新のバックアップからファイルを復元してください。
そこにあるファイルに関しては、コピーされたファイルのみを削除したいです。これらのファイルは両方のディレクトリに存在し、名前も同じで、内容も同じです。
そこで、次のファイルを探します。
まず、cd
に入りますsrc
。これにより、次の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
どうかを確認します。これにより、最初に確認することでファイルの上書きを防ぐことができます。
答え3
これは古いですが、純粋な bash の回答を投稿したかっただけです。
まず、ファイルをコピーしたディレクトリに移動します。
cd dest
次に、ls
ソースディレクトリと出力をパイプしますrm
ls source | xargs rm
答え4
これは、コピー操作のタイムスタンプに基づいた回答です。フォルダーの内容を作成時刻順にリストし、ファイルにパイプすることができます。
ls -alt | file_list
次に、file_list
コピー操作と同じタイムスタンプを持つファイルを開いて探します。おそらく、これらが最新のファイルになります。
次に、不要なファイル/フォルダーfile_list
を編集して保存します。rm -rf
次に、次の操作を実行します。
source file_list