디렉토리에 파일 이름별로 정렬된 많은 파일이 있습니다. 마지막 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) ~/