list.txt의 이름 파일을 제외한 폴더의 파일을 삭제하는 방법은 무엇입니까?

list.txt의 이름 파일을 제외한 폴더의 파일을 삭제하는 방법은 무엇입니까?

폴더에 /photo많은 파일이 있다고 가정합니다.

1.jpg
2.jpg
3.jpg
4.jpg
5.jpg
6.jpg
7.jpg
8.jpg
9.jpg
10.jpg

nodeletelist.txt이 텍스트 파일에는 삭제하지 않을 파일 목록의 이름과 함께 파일 이름이 있습니다.

1.jpg
2.jpg
3.jpg
nodeletelist.txt

파일을 삭제하는 방법:

4.jpg
...
10.jpg

파일을 제외하고 1.jpg, 2.jpg및 무엇 3.jpg입니까 ?nodeletelist.txtnodeletelist.txt

답변1

GNU 발견이 있나요?

find photo -mindepth 1 -maxdepth 1 -regextype awk \! -regex ".*/($(tr '\n' '|' < photo/nodeletelist.txt)nodeletelist.txt)" -delete

이는 tr(1)및 를 사용하여 달성됩니다 find(1).

  1. 파일을 다음으로 리디렉션tr
  2. 줄 바꿈을 "OR"을 의미하는 수직 막대로 바꿉니다.
  3. 서브쉘에서 복귀
  4. 파일이 개행으로 끝나는 경우 끝에 플래그 값을 추가하십시오. (이 예에서는 귀하의 이름을 감시자로 사용하므로 nodeletelist.txt이 솔루션을 사용하는 경우 파일에 파일 이름을 포함할 필요가 없습니다.)
  5. 디렉토리에서 한 수준 아래 항목을 검색하세요.photo
  6. awk 정규식을 사용하여 위의 1~4단계에서 반환된 문자열을 일치시킵니다.
  7. 파일 삭제아니요정규식과 일치함( !"NOT"을 의미하므로)

여기에 필요한 확장 구문이 해당 플래그에 적용되므로 여기 플래그는 , , 또는 -regextype로 설정할 수도 있습니다 . 기본 findutils 정규식, posix-basic, emacs, sed 등은 이 명령에서 작동하지 않습니다.posix-extendedegrepposix-egrepgnu-awkposix-awk

답변2

zsh그것이 옵션 이라면 , 다음과 같이 사용할 쉘 함수를 정의할 수 있습니다.글로벌 예선"는 glob의 모든 파일 목록을 필터링하는 데 사용됩니다 *. 예를 들어

 % cmd() { ! grep -qF "$REPLY" ./nodeletelist.txt ; } 

그런 다음 ( photo/디렉토리에서)

 % ls
 10.jpg   1.jpg   2.jpg   3.jpg   4.jpg   5.jpg   6.jpg   7.jpg   8.jpg   9.jpg   nodeletelist.txt
    
 % ls *(+cmd)                                         
10.jpg  4.jpg  5.jpg  6.jpg  7.jpg  8.jpg  9.jpg

괜찮아 보이는데 삭제하자

 % rm *(+cmd)

 % ls
1.jpg  2.jpg  3.jpg  nodeletelist.txt

먼저 파일을 배열로 매핑한 다음 해당 파일이 $REPLY배열의 요소인지 테스트하는 보다 효율적인 구현이 있을 수 있습니다.

답변3

나에게는 가장 간단하고 기억하기 쉬우며 많은 파일에서도 작동합니다(파일 이름의 줄 바꿈에서 생각이 깨질 수 있지만 그런 경우 목록에 대해 생각해야 합니다).

cd /photo
ls -1 | grep -v -x -f nodeletelist.txt | xargs -d "\n" -P 0 rm -f

디렉터리에 다른 항목(하위 디렉터리 또는 다른 파일, 목록에 txt가 포함되어 있다고 가정하지 않음)이 있는 경우 ls 대신 find I를 사용합니다( find . -maxdepth 1 -type f -name "*.jpg"예:).

답변4

설명된 이름에 공백이 없는 경우

rm $(join -v 1 <(ls *.jpg) <(sed '$ d' nodeletelist.txt))

nodeletelist.txt 파일의 마지막 줄을 실제로 읽었다고 가정합니다.nodeletelist.txt

그렇지 않다면,

rm $(join -v 1 <(ls *.jpg) nodelete.txt)

근데 별로 고급스러운 느낌은 아닌데...

관련 정보