상당히 간단한 스크립트를 작성하려고 하는데 특정 파일을 건너뛰는 합리적인 방법을 찾을 수 없습니다.
주어진 순서대로 모든 파일을 나열하고 싶습니다. 목록에 10개 이상의 파일이 포함된 경우 11-n 파일을 삭제하고 첫 번째(또는 마지막) 10개 파일을 유지하고 싶습니다.
/TLDR: 다음 명령으로 파이프하기 전에 find/ls/whatever 결과에서 고정된 수의 파일을 건너뛰는 방법
주어진 패턴을 가진 모든 파일을 이름별로 정렬하고 10개 이상이면 삭제하고 싶습니다.
답변1
사용 zsh
모드
*(.[11,-1])
현재 디렉터리에 있는 일반 파일의 모든 이름(디렉터리 이름 등 제외)을 일치시키고 이름별로 정렬하고(기본 정렬 순서) 처음 10개 이름을 제외한 모든 이름을 반환합니다.
시험:
$ touch file-{01..20}
$ ls
file-01 file-03 file-05 file-07 file-09 file-11 file-13 file-15 file-17 file-19
file-02 file-04 file-06 file-08 file-10 file-12 file-14 file-16 file-18 file-20
$ printf '%s\n' *(.[11,-1])
file-11
file-12
file-13
file-14
file-15
file-16
file-17
file-18
file-19
file-20
당신은 원하십니까?삭제다음 파일:
$ rm *(.[11,-1])
$ ls
file-01 file-02 file-03 file-04 file-05 file-06 file-07 file-08 file-09 file-10
이 점에 유의하시기 바랍니다필요zsh
다른 쉘과 마찬가지로 이 쉘은 bash
사용되는 특수한 유형의 와일드카드 패턴을 이해하지 못합니다.
다른 쉘에서 사용할 수 있습니다
zsh -c 'rm *(.[11,-1])'
당신은 bash
다음과 같은 것을 할 수 있습니다
names=( * )
printf '%s\n' "${names[@]:10}"
삭제하려는 파일 이름을 나열하지만 나열된 이름이 일반 파일의 이름이거나 디렉터리 이름일 가능성이 높다는 보장은 없습니다. 따라서 다음을 반복하고 싶을 수도 있습니다.
for name in *; do
if [ -f "$name" ]; then
files+=( "$name" )
fi
done
printf '%s\n' "${files[@]:10}"
그러면 일반 파일을 가리키는 심볼릭 링크의 이름도 얻게 됩니다.
이를 제거하려면 를 사용하십시오 rm "${files[@]:10}"
.
데이터를 삭제하는 모든 작업과 마찬가지로 모든 솔루션을 테스트합니다.복사실제로 실행하기 전에 실제 데이터를 얻으십시오.
답변2
귀하가 수행하려는 작업에 대해 매우 모호한 설명을 제공했기 때문에 이 답변도 마찬가지로 모호할 수 있지만 다음과 같습니다.
head
그리고 tail
이 목적을 위해 설계되었습니다.
처음 10개의 결과를 제외한 모든 결과를 무시하려면 다음을 사용하십시오.
head -n 10
마지막 10개 결과를 제외한 모든 결과를 무시하려면 다음을 사용하십시오.
tail -n 10
참고: 이는 결과가 줄바꿈으로 구분된 경우에만 작동합니다.