디렉토리의 마지막 N개 파일을 얻는 방법은 무엇입니까?

디렉토리의 마지막 N개 파일을 얻는 방법은 무엇입니까?

디렉토리에 파일 이름별로 정렬된 많은 파일이 있습니다. 마지막 N개(N=4라고 가정) 파일을 내 홈 디렉터리에 복사하고 싶습니다. 어떻게 해야 하나요?

cp ./<the final 4 files> ~/

답변1

이는 bash/ksh93/zsh 배열을 사용하여 쉽게 수행할 수 있습니다.

a=(*)
cp -- "${a[@]: -4}" ~/

이는 공백, 탭, 줄 바꿈 또는 기타 어려운 문자가 포함된 경우에도 숨겨지지 않은 모든 파일 이름에 대해 작동합니다(현재 디렉토리에 숨겨지지 않은 파일이 4개 이상 있다고 가정 bash).

어떻게 작동하나요?

  • a=(*)

    a그러면 모든 파일 이름을 포함하는 배열이 생성됩니다. Bash에서 반환된 파일 이름은 알파벳순으로 정렬됩니다. (내 생각에는 이것이 바로 당신의 뜻인 것 같다."파일 이름으로 정렬하세요.")

  • ${a[@]: -4}

    그러면 배열의 마지막 4개 요소가 반환됩니다 a(배열에 가 포함된 요소가 4개 이상 포함되어 있는 경우 bash).

  • cp -- "${a[@]: -4}" ~/

    그러면 마지막 4개의 파일 이름이 홈 디렉터리에 복사됩니다.

동시에 복사하고 이름 바꾸기

a_그러면 마지막 4개 파일만 홈 디렉터리에 복사되고 복사된 파일 이름 앞에 문자열이 추가됩니다 .

a=(*)
for fname in "${a[@]: -4}"; do cp -- "$fname" ~/a_"$fname"; done

다른 디렉토리에서 복사하고 이름을 바꿉니다.

a=(./some_dir/*)대신 사용하면 a=(*)파일 이름에 디렉터리가 추가되는 문제가 발생합니다. 한 가지 해결책은 다음과 같습니다.

a=(./some_dir/*) 
for f in "${a[@]: -4}"; do cp "$f"  ~/a_"${f##*/}"; done

또 다른 해결책은 서브셸을 사용하고 cd서브셸의 디렉터리에 액세스하는 것입니다.

(cd ./some_dir && a=(*) && for f in "${a[@]: -4}"; do cp -- "$f" ~/a_"$f"; done) 

하위 쉘이 완료되면 쉘은 원래 디렉토리로 돌아갑니다.

순서가 일관된지 확인하세요.

질문은 "파일 이름으로 정렬된" 파일에 대해 묻습니다. Olivier Dulac은 자신의 논평에서 이 순서가 지역에 따라 달라질 것이라고 언급했습니다. 시스템 설정과 관계없이 고정된 결과가 중요한 경우 a배열을 정의할 때 로케일을 명시적으로 지정 하는 것이 좋습니다 . 예를 들어:

LC_ALL=C a=(*)

이 명령을 실행하면 현재 어떤 로케일에 있는지 확인할 수 있습니다 locale.

답변2

다음을 사용하는 경우 소위 목록을 괄호로 묶을 zsh수 있습니다.()글로벌 예선필요한 파일을 선택하세요. 귀하의 경우에는

cp *(On[1,4]) ~/

여기에서는 On파일 이름이 알파벳 역순으로 정렬되어 [1,4]처음 4개만 사용됩니다.

이름이 올바른 파일로 시작하는 파일을 올바르게 처리하기 위해 명령을 사용하여 일반 파일(디렉토리, 파이프 등 제외)만 선택하고 명령 에 .추가 하면 더욱 강력하게 만들 수 있습니다.--cp-

cp -- *(.On[1,4]) ~

D숨겨진 파일(점 파일)도 고려하려면 한정자를 추가하세요.

cp -- *(D.On[1,4]) ~

답변3

이것은 매우 간단한 bash 명령을 사용하는 솔루션입니다.

find . -maxdepth 1 -type f | sort | tail -n 4 | while read -r file; do cp "$file" ~/; done

설명하다:

find . -maxdepth 1 -type f

현재 디렉터리에서 모든 파일을 찾습니다.

sort

알파벳순으로 정렬합니다.

tail -n 4

마지막 4줄만 표시됩니다.

while read -r file; do cp "$file" ~/; done

복사 명령의 각 줄을 반복합니다.

답변4

파일만 있고 파일 이름에 공백이나 개행 문자(수정하지 않은 경우 $IFS) 또는 전역 문자(또는 일부 구현에서는 인쇄할 수 없는 일부 문자 ls)가 포함되어 있지 않고 다음으로 시작하지 않는 경우 .:

cp -- $(ls | tail -n 4) ~/

관련 정보