파일 이름 X에서 파일 이름 Y로 여러 파일을 복사하시겠습니까?

파일 이름 X에서 파일 이름 Y로 여러 파일을 복사하시겠습니까?

내가 하고 싶은 것은 사전 범위 내의 파일을 복사하는 것입니다.

파일 예:

-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.jpgwill 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

관련 정보