최신 파일을 제외한 모든 파일 삭제


8

ḟoo/디렉토리 구조의 일종으로 많은 파일을 포함 하는 디렉토리가 있다고 가정 해 봅시다 . 나는 그들 중 일부를 유지해야하지만 전부는 아닙니다.

500을 제외한 모든 것을 삭제하는 방법이 있습니까?

답변:


11

이 작업을 정기적으로 수행하고 다음과 같은 변형을 사용합니다. 다양한 간단한 도구를 결합한 파이프 라인입니다. 모든 파일 찾기, 파일 수정 시간 앞에 붙이기, 정렬, 파일 수정 시간 제거, 500을 제외한 모든 줄 표시 및 제거 :

find foo/ -type f | perl -wple 'printf "%12u ", (stat)[9]' | \
    sort -r | cut -c14- | tail -n +501 | \
    while read file; do rm -f -- "$file"; done

몇 가지 의견 :

  • "bash"를 사용하는 경우 "read file"뿐만 아니라 "read -r file"을 사용해야합니다.

  • "perl"을 사용하여 파일을 제거하는 것이 더 빠릅니다 (또한 "read -r file"을 사용하지 않는 한 while-loop보다 파일 이름에서 "이상한"문자를 처리합니다).

    ... | tail -n +501 | perl -wnle 'unlink() or warn "$_: unlink failed: $!\n"'
    
  • 일부 "tail"버전은 "-n"옵션을 지원하지 않으므로 "tail +501"을 사용해야합니다. 500 개의 첫 줄을 건너 뛰는 휴대용 방법은

     ... | perl -wnle 'print if $. > 500' | ...
    
  • 파일 이름에 줄 바꿈이 포함되어 있으면 작동하지 않습니다.

  • GNU find가 필요하지 않습니다.

위의 내용을 결합하면 다음이 가능합니다.

find foo/ -type f | perl -wple 'printf "%12u ", (stat)[9]' | \
    sort -r | cut -c14- | perl -wnle 'print if $. > 500' | \
    perl -wnle 'unlink() or warn "$_: unlink failed: $!\n"'

rm -f그래도 조심할 것 입니다.
CVn

매력처럼 작동합니다! $ path 및 $ count 매개 변수가있는 별명으로 사용 가능해야합니다. 고마워요!
달리 보르 카를로 비치

4

이것이 파이썬 3에서 수행하는 방법입니다. 다른 OS에서도 작동합니다. 이를 테스트 한 후 실제로 파일을 제거하는 행의 주석을 해제하십시오.

import os,os.path
from collections import defaultdict

FILES_TO_KEEP = 500
ROOT_PATH = r'/tmp/'

tree = defaultdict(list)

# create a dictionary containing file names with their date as the key
for root, dirs, files in os.walk(ROOT_PATH):
    for name in files:
        fname = os.path.join(root,name)
        fdate = os.path.getmtime( fname )
        tree[fdate].append(fname)

# sort this dictionary by date
# locate where the newer files (that you want to keep) end
count = 0
inorder = sorted(tree.keys(),reverse=True)
for key in inorder:
    count += len(tree[key])
    if count >= FILES_TO_KEEP:
        last_key = key
        break

# now you know where the newer files end, older files begin within the dict
# act accordingly
for key in inorder:
    if key < last_key:
        for f in tree[key]:
            print("remove ", f)
            # uncomment this next line to actually remove files
            #os.remove(f)
    else:
        for f in tree[key]:
            print("keep    ", f)

4

"500 최신"에 대해 잘 모르겠지만 X 분 / 일보다 오래된 항목을 삭제할 수 있습니다. 2 일이 지난 파일의 예 :

find foo/ -mtime +2 -a -type f -exec rm -fv \{\} \;

먼저 다음을 테스트하십시오.

find foo/ -mtime +2 -a -type f -exec ls -al \{\} \;

"\;"앞의 백 슬래시와 공백을주의하십시오. 자세한 내용은 find 맨 페이지를 참조하십시오.


여기서 "(500) 최신"이 본질이므로 이것이 원래 질문에 어떻게 대답하는지 알 수 없습니다.
피터 존 악클

죄송합니다. 명확하지 않았습니다.
AndreasM

3

최신 x 번호 대신 x 일 / 시간 오래된 파일을 유지할 수 있다면 다음과 같이 할 수 있습니다. tmpwatch --ctime 7d


2

명령 옵션 -mtime-newer옵션 find이 유용 하다고 생각합니다 . man find자세한 내용 을 볼 수 있습니다 .


0

이 간단한 코드를 사용하지 않는 이유 :

$ ls -t1 foo/| xargs -d '\n' rm --

1
이렇게하면 500 개의 최신 파일을 제외한 모든 파일이 어떻게 제거됩니까? 그리고 이것이 하위 디렉토리를 어떻게 처리합니까? 원래 게시물을 잘못 이해했을 수도 있습니다.
피터 존 악클
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.