다른 디렉터리의 모든 파일을 삭제하고 최신 20개 파일만 유지하고 싶습니다. 이 작업을 수행하는 올바른 명령입니까?
ls -t1 /mnt/dwh/ftp/dwh_ftp_cbs/ARLOGS/ | tail -n +22 | xargs rm -f
답변1
그리고 zsh
그리고글로벌 예선:
print -rl -- *(D.Om[1,-21])
마지막(가장 최근에 수정된) 20개 파일을 제외한 모든 일반 파일이 나열됩니다.
D
숨김 파일 선택, .
일반 파일만 선택, Om
역순 정렬을 의미합니다.시간(오래된 것부터) 그리고 [1,-21]
마지막부터 처음부터 21일까지 선택하세요.
결과가 만족스러우면 다음 print -rl
으로 바꾸세요 rm
.
rm -- *(D.Om[1,-21])
파일 수가 많으면 사용을 zargs
피해야 할 수도 있습니다.매개변수 목록이 너무 깁니다.:
autoload zargs
zargs ./*(D.Om[1,-21]) -- rm
답변2
ls
교리문답인 출력 처리 등 명령에 많은 단점이 있습니다 . 바라보다이 기사왜 이렇게하지 않습니까?
이 방법은아니요GNU 확장이며 bash, zsh, ksh93, dash 및 ash에서 테스트되었습니다.
for f in * .*; do
[ -f "$f" ] && printf "%s " $(perl -e 'print((stat("$ARGV[0]"))[9])' -- "$f") && \
printf "%s\0" "$f";
done | tr '\0\n' '\n\0' | sort -k1nr | \
sed "1,20d;s/'/'\"'\"'/g;s/[^ ]* \(.*\)/rm -f -- '\1';/" | tr '\0' '\n' | sh
이것은 내가 생성할 수 있었던 가장 이상한 파일 이름이며 심지어 작동합니다.
touch -- '--a'"'"'b"c
d$e\nf\r!g;h^i`j(k)l*m%n=o?p.txt'
또는 파일 이름에서 "점프 아웃"해 보십시오.
touch '\'"'"'echo test '"'"'\'
답변3
ls -t1 /mnt/dwh/ftp/dwh_ftp_cbs/ARLOGS/ | tail -n +22 | xargs rm -f
의 출력에는 ls
전체 경로가 아닌 파일 이름만 포함되므로 작동하지 않습니다. 또한 로 시작하는 이름도 건너뜁니다 .
.
cd /mnt/dwh/ftp/dwh && ls -At1 | tail -n +21 | xargs rm -f --
이 문제는 해결될 수 있지만 공백, 개행, 아포스트로피, 백슬래시 또는 큰따옴표 문자가 포함된 파일 이름에는 여전히 문제가 있습니다(그리고 파일 이름에는 로케일에서 유효한 문자를 형성하지 않는 바이트가 포함될 수 있습니다).
(export LC_ALL=C
cd /mnt/dwh/ftp/dwh && ls -At1 |
tail -n +21 |
sed 's/"/\\"/g;s/.*/"&"/' |
xargs rm -f --
)
이렇게 하면 대부분의 문제가 해결되지만 개행 문자가 포함된 파일 이름에는 여전히 문제가 있습니다. 문제는 출력을 ls -At1
사후 처리할 수 없다는 것입니다.
의 출력은 ls -Atd1 ./.* ./*
후처리될 수 있습니다(이 ./
접두사는 출력에서 각 파일 이름이 시작되는 위치를 나타내기 때문에 쉽지는 않지만). 파일 이름 목록을 전달하면 명령에 전달되는 인수 수 제한에 도달할 위험이 있습니다 ls
.
가장 좋은 방법은전역 정렬이 가능한 쉘을 사용하세요., 또는 GNU 시스템에서만 작업해야 하는 경우 GNU 확장을 사용하세요.
cd /mnt/dwh/ftp/dwh &&
find . ! -name . -prune ! -type d -printf '%T@\t%p\0' |
tr '\0\n' '\n\0' |
sort -rn |
tail -n +21 |
cut -f 2- |
tr '\0\n' '\n\0' |
xargs -r0 rm -f
여기서는 파일 형식을 제외합니다.목차, 이는 번호 매기기에 영향을 주지만 디렉토리를 삭제하고 싶지 않을 것이라고 생각하기 때문에 아마도 원하는 것에 더 가깝습니다. 디렉토리를 제거하려면 해당 -type d
옵션을 삭제하고 .-r
rm
또는:
eval "set -- $(COLUMNS=4294967295 ls -Atx --quoting-style=shell-always)"
if [ "$#" -gt 20 ]; then
shift 20
printf '%s\0' "$@" | xargs -r0 rm -f --
fi
perl
또는 , python
, ruby
... 와 같은 범용 프로그래밍 언어를 사용하십시오.