다음에 나열된 경로의 파일을 제외하고 디렉터리의 모든 파일을 삭제합니다.

다음에 나열된 경로의 파일을 제외하고 디렉터리의 모든 파일을 삭제합니다.

다음 파일이 제공됩니다.

data/A/a.txt
data/B/b.pdf
...
date/P/whatever.log
...
data/Z/z.jpg

data/A/, data/B/, ... data/Z/디렉토리의 모든 파일을 삭제하고 싶습니다 .와는 별개로파일에 나열된 디렉터리 중 하나 아래에 있는 파일입니다 data/dont_clean.txt. 예를 들어 나열한 경우 data/P아래 data/dont_clean.txt에는 아무것도 건드리면 안 됩니다 data/P/.

그것은 다음과 같습니다:

find data/ -mindepth 2 -maxdepth 2 -type f -not -path {listed in data/dont_clean} -delete

물론 이것은 유효한 명령이 아닙니다.

내가 시도한 변형

find data/ -mindepth 2 -maxdepth 2 -type f -exec grep data/dont_clean.txt '{}' \;

하지만 방금 잘못된 명령을 생성했거나 내가 수행한 출력을 얻은 이유를 모르겠습니다.

우분투 12.10에서 bash를 사용하고 있습니다

답변1

다음은 대략적으로 테스트한 코드이지만, 방법을 알려줄 수도 있습니다. 다음과 같은 파일이 있다고 가정해 보겠습니다 ignore.txt.

1/
2/

견본

다음과 같은 파일이 포함된 샘플 디렉터리가 있습니다.

$ mkdir -p dirs/{1..5}
$ touch dirs/{1..5}/afile

결과는 다음과 같습니다.

$ tree dirs/
dirs/
|-- 1
|   `-- afile
|-- 2
|   `-- afile
|-- 3
|   `-- afile
|-- 4
|   `-- afile
`-- 5
    `-- afile

예제 실행

이제 이 트리에 대해 이 명령을 실행하면 다음과 같습니다.

$ find dirs/ -type f -print0 | fgrep -zFvf ./ignore.txt
dirs/5/afiledirs/4/afiledirs/3/afile

에 나열되지 않은 디렉터리의 파일만 가져오는 것을 볼 수 있습니다 ignore.txt.

따라서 rm제외되지 않은 파일을 제거하기 위해 끝에 하나를 추가할 수 있습니다.

$ find dirs/ -type f -print0 | fgrep -zFvf ./ignore.txt | xargs -0 rm -f

검사해 보면 작동하는 것을 볼 수 있습니다.

$ tree dirs/
dirs/
|-- 1
|   `-- afile
|-- 2
|   `-- afile
|-- 3
|-- 4
`-- 5

해결이 필요한 문제

이 접근 방식의 큰 문제는 파일의 문자열이 ignore.txt디렉터리 구조의 다른 부분과 일치할 수 있다는 것입니다. 따라서 이 파일의 문자열이 예상한 대로 고유한지 확인하기 위해 주의를 기울여야 합니다.

로프 주위에 일부 장벽을 배치하여 로프를 보호하기 위해 로프의 시작 부분이나 끝 부분에 고정할 수 있습니다.

세부 사항

위 명령은 다음을 수행합니다.

  1. 디렉토리의 모든 파일 찾기dirs
  2. igonre.txt파일이 존재하는 디렉터리의 모든 파일을 필터링합니다.
  3. 필터 목록을 명령 xargs에 전달rm -f

답변2

해당 명령의 예인 것 같습니다 comm.

list of files to not delete in "keeper"
ls >current
comm -23 current ../keeper | more

목록이 맞는지 확인해보세요

comm -23 current ../keeper | xargs rm

답변3

xargs그리고 find조합

데모:

내 파일:

[root@mail tmp]# find data/ -type f
data/A/d.txt
data/A/b.txt
data/A/a.txt
data/A/c.txt
data/B/e.txt
data/B/g.txt
data/B/f.txt
data/B/i.txt

제외 목록

[root@mail tmp]# cat exclude 
data/A/a.txt
data/B/e.txt

xargs를 사용하여 찾기

[root@mail tmp]# find data/ -type f $( xargs  -I{} echo -n " -not -path {} " < exclude )
data/A/d.txt
data/A/b.txt
data/A/c.txt
data/B/g.txt
data/B/f.txt
data/B/i.txt

출력이 괜찮은 것 같으니 삭제해 보겠습니다. 하지만 그 전에 다음 명령의 출력이 괜찮은지 확인한 다음 두 번째에서 마지막 echo명령을 삭제할 수 있습니다.

[root@mail tmp]# find data/ -type f $( xargs  -I{} echo -n " -not -path {} " < exclude ) | xargs -n1 echo rm -rf
rm -rf data/A/d.txt
rm -rf data/A/b.txt
rm -rf data/A/c.txt
rm -rf data/B/g.txt
rm -rf data/B/f.txt
rm -rf data/B/i.txt

답변4

이 작업은 두 단계로 수행할 수 있습니다. 태그를 지정하고(고유하게 만들기 위해) 보호되지 않은 콘텐츠를 제거하는 것입니다.

이러한 파일이 모두 동일한 사용자의 것인 경우 이 목록을 사용하여 소유권이나 그룹을 다른 사용자로 변경할 수 있습니다. 그런 다음 find를 사용하여 나머지를 삭제하고 사용자를 다시 변경하십시오. 모든 파일에 동일한 읽기 권한이 있는 경우(다시 전환하는 방법을 알고 있는 경우) 사용자를 변경하는 것보다 훨씬 쉽기 때문에(루트 권한이 필요하지 않음) 읽기 권한을 제거(표시)할 수 있습니다.

while read file; do chmod u-w -R "$file"; done < "data/dont_clean.txt"
find data/ -mindepth 2 -maxdepth 2 -type f -writable -delete
while read file; do chmod u+w -R "$file"; done < "data/dont_clean.txt"

전체 디렉터리를 보호하려면 편집(재귀 추가)하세요. chmod 재귀 문제를 방지하려면 권한을 읽기에서 쓰기로 변경하세요(방금 변경한 디렉터리를 읽을 수 없음).

관련 정보