복사 (cp) 명령 실행 취소


14

터미널의 다음 명령 줄을 사용하여 소스 폴더에서 대상 폴더로 일부 파일을 복사했습니다.

sudo cp From_SOURCE/* To_DESTINATION/

이제이 명령을 취소하고 싶습니다.


잘 모르겠습니다. 단순히 사본을 제거 하시겠습니까? (sudo rm 파일)
Jacob Vlijm

@JacobVlijm 그것은 실행 취소가 아니며 별도의 명령입니다. 복사하지 않았다면 이전에 제안한 명령을 사용할 수 있습니다. 그리고이 명령을 사용하여 복사 된 1000 개 이상의 파일을 삭제하는 데 점점 더 많은 시간이 필요합니까?
αғsнιη

@KasiyA-옵션은에서 선택한 모든 파일 이름을 찾아서 From_SOURCE/*제거합니다 To_DESTINATION/. 이것은 bash를 사용하여 수행 할 수 있습니다. 여기의 문제에는 cp 명령이 무엇이든 덮어 썼거나 symlinks가 복사되었거나 이름이 공백이있는 파일 등이있을 수 있습니다. 따라서 문제가 있고 약간 엉뚱 할 수 있습니다. 완벽한 '실행 취소'옵션은 많은 것들을 설명해야 할 것입니다.
Wilf

답변:


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
    

경고

달성해야 할 것을 잘 이해했다면 먼저 테스트 디렉토리에서 시도하십시오!


소스 디렉토리가 "flat"인 경우

소스 디렉토리에 서브 디렉토리가없는 경우 스크립트가 더 간단해질 수 있습니다.

#!/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нιη

완전한! 우리 모두가 있었던 상황을 설명하는 멋진 질문에 감사드립니다.)
Jacob Vlijm

참고 : 소스에 있는 파일이 동일한 이름을 가지고 있기 때문에 대상에있는 파일을 덮어 쓴 경우 단순히 실행 취소 할 수 없으며이 스크립트는 파일을 삭제합니다. 여기에서의 가정은 당신이 이니셜을했을 때 이름 충돌이 없었다는 것 cp입니다.
thomasrutter

@neon_overload 올 바르고 답을 편집했습니다.
Jacob Vlijm

이 기능은 작동하지 않습니다 cp -r. 나는 변화 os.remove와 함께 print, 그것은 존재하지 않는 파일들을 출력합니다. 하위 디렉토리가 누락되어 파일 끝에 만 나열한다고 가정합니다.
Typewar

7

TL; DR :

두 파일 모두에 있으며 다음 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_SOURCEdestTo_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). 너무 늦어서 죄송합니다. 최신 백업에서 다시 가져옵니다.

존재하는 파일에 대해서는 복사 한 파일 만 제거하려고합니다. 이러한 파일은 동일한 이름과 동일한 컨텐츠를 가진 두 디렉토리에 모두 존재합니다.

그래서 우리는이 파일들을 찾습니다 :

첫째, cdsrc,이 다음 만들기 때문에 find훨씬 간단 명령을하고, 이명 령의 절대 경로에 변수를 설정 :

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

그런 다음 src의 모든 파일을 나열합니다.

$ find . -maxdepth 1 -type f

발견 된 각 파일에 대해 cmpdest에 동일한 내용의 파일이 있는지 확인하십시오.

$ 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, 아직 실제로에서 같은 srcdest,에있다 /tmp/toDelete/, 그리고 마지막 모습을 촬영 한 후 제거 할 수 있습니다.


참고 :
(1) cp별명 인지 여부를 cp -i먼저 확인하여 파일 덮어 쓰기를 방지 했는지 확인하십시오 .


5

이것은 오래되었지만 순수한 bash 답변을 게시하고 싶었습니다.

먼저 파일을 복사 한 디렉토리로 변경하십시오.

cd dest

그런 다음 ls소스 디렉토리와 출력을 파이프rm

ls source | xargs rm


1
파싱 ls은 일반적으로 나쁜 생각입니다. mywiki.wooledge.org/ParsingLs 게시물을 공개하지는 않지만 주목해야합니다.
Sergiy Kolodyazhnyy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.