내가 하고 싶은 것은 사전 범위 내의 파일을 복사하는 것입니다.
파일 예:
-rw-r--r-- 1 root root 15276 Oct 5 2004 a2ps.cfg
-rw-r--r-- 1 root root 2562 Oct 5 2004 a2ps-site.cfg
-rw-r--r-- 4 root root 4096 Feb 2 2007 acpi.txt
-rw-r--r-- 1 root root 48 Feb 8 2008 adjtime.jpg
-rw-r--r-- 4 root root 4096 Feb 2 2007 alchemist.jpg
사용 예:
- 3개의 파일을 에서 로 복사하세요
asps.cfg
.acpi.txt
- 3개의 파일을 에서 로 복사하세요
a2ps-site.cfg
.adjtime.jpg
- 4개의 파일을 에서 로 복사하세요
a2ps-site.cfg
.alchemist.jpg
그렇다면 일련의 파일(파일 이름 X에서 파일 이름 Y까지)을 디렉터리에 복사하는 방법이 있습니까?
좋다:cp filenameX ... filenameY destination/
답변1
일반적인 접근 방식은 일련의 파일 이름을 인쇄하는 셸 함수를 정의하는 것입니다. 이 함수의 간단한 버전은 현재 디렉터리의 두 파일 이름 사이에 있는 모든 파일을 나열합니다.
range()
{
ls | sed -n "/^$1\$/,/^$2\$/p"
}
이는 sed 범위를 사용하여 주어진 두 문자열( $1
및 ) $2
사이의 모든 항목을 인쇄합니다.
cp(1)
그런 다음 명령에서 이 기능을 사용할 수 있습니다 .
cp $(range asps.cfg acpi.txt) /destination/path
파일 이름에 공백이 포함되어 있으면 이 작업이 실패합니다. 이렇게 하려면 좀 더 정교해져야 합니다.
range asps.cfg acpi.txt | xargs -d '\n' -I {} cp {} /destination/path
파일 이름에 개행 문자(\n)가 포함되어 있으면 작업이 실패합니다. 그럴 가능성은 거의 없으므로 이 문제를 해결하는 것은 독자의 연습 문제로 남겨 둡니다.
이것을 다른 쉘 함수에 함께 넣을 수 있습니다:
cprange()
{
[ $# -eq 3 ] || { echo "usage: cprange start end dir" >&2; return 1;}
range "$1" "$2" | xargs -d '\n' -I {} cp {} "$3"
}
다음과 같이 사용하세요.
cprange filenameX filenameY destination
범위는 현재 디렉터리의 파일 이름에만 적용된다는 점을 기억하세요. 이를 다양한 방법으로 확장할 수 있습니다(디렉토리 매개변수 추가 range
, 매개변수에서 range
사용 으로의 경로 추출 dirname
등). 하지만 요구사항에 따라 결정하도록 하겠습니다. 더 자세한 내용이 필요하시면 여기로 문의해주세요.
답변2
Zsh에는 glob 결과에서 다양한 파일을 선택하는 쉬운 방법이 있습니다(glob은 와일드카드 일치입니다). 장점은 명령이 작성하기 짧다는 것입니다. 마이너스 사이트에서는 쓸 파일의 시퀀스 번호를 알아내야 합니다. 예를 들어, 다음 명령은 .jpg
현재 디렉터리에서 확장명이 있는 21번째, 22번째,..., 40번째 파일을 복사하고 파일은 알파벳 순서로 나열됩니다.
cp *.jpg([21,40]) destination/
Zsh에는 도움이 될 수도 있고 그렇지 않을 수도 있는 옵션이 있습니다. under setopt numeric_glob_sort
, foo9bar.jpg
will sort before foo10bar.jpg
. cp *.jpg(om[21,40]) destination/
21번째부터 40번째까지의 가장 최근 파일을 선택하는 등 ( O
대문자를 사용하여 역순으로 정렬) glob 한정자에서 다른 정렬 순서를 선택할 수도 있습니다. 바라보다글로벌 예선매뉴얼에서 자세히 알아보세요.
모든 셸에서 파일을 반복하여 기록할 첫 번째 파일부터 복사를 시작하고 마지막 파일 이후에 중지하는 루프를 작성할 수 있습니다. 경고, 테스트되지 않았습니다.
in_range=
for x in *.jpg; do
if [ "$x" = "first-file.jpg" ]; then in_range=1; fi
if [ -n "$in_range" ]; then cp "$x" destination/; fi
if [ "$x" = "last-file.jpg" ]; then break; fi
done
답변3
이 예에서 가장 간단한 것은 M-*를 사용하여 패턴을 완성하고 복사하고 싶지 않은 패턴을 제거하는 것입니다.
% cp *[hit Escape and press *]
->
% cp file1 file2 file3 file4 ...
그런 다음 복사하지 않을 파일을 수동으로 삭제하세요. 어쨌든 이것은 셸 기능이 아니라 cp
.
필요에 따라 패턴을 다듬을 수 있습니다. 디렉토리에 다른 파일이 많이 있고 로 시작하는 파일만 복사하려는 경우 a
해당 문자로 패턴을 시작하면 됩니다. 파일 이름 글로빙에 대한 쉘 문서를 찾아볼 수도 있습니다. 예를 들어,http://tldp.org/LDP/abs/html/globbingref.html.
답변4
파일명을 정리해서 같은 분량으로 배포하시는 것 같네요.
모든 파일 이름을 하나의 파일에 저장
ls > all_files
파일을 배치로 분할
split -l 4 all_files all_files-
이제 각 파일에는 4개의 파일 이름이 있습니다.all_files-*
하나를 골라 말하고 all_files-aa
복사해 보세요.
xargs -I{} cp {} folder_for_batch_1 < all_files-aa