폴더의 모든 4 번째 파일을 복사하는 방법


15

폴더에 이름이 같은 많은 파일이 있습니다 00802_Bla_Aquarium_XXXXX.jpg. 이제 모든 4 번째 파일을 하위 폴더 에 복사해야합니다 selected/.

00802_Bla_Aquarium_00020.jpg <= this one
00802_Bla_Aquarium_00021.jpg
00802_Bla_Aquarium_00022.jpg
00802_Bla_Aquarium_00023.jpg
00802_Bla_Aquarium_00024.jpg <= this one
00802_Bla_Aquarium_00025.jpg
00802_Bla_Aquarium_00026.jpg
00802_Bla_Aquarium_00027.jpg
00802_Bla_Aquarium_00028.jpg <= this one
00802_Bla_Aquarium_00029.jpg

어떻게해야합니까?


의 일부 출력 에서 superuser.com/q/396536/87552 에 대한 솔루션을 좋아할 수 있습니다 ls. 매초마다 물어 보는 stackoverflow.com/q/4553751/789593 도 참조하십시오 .
NN

번호가 매겨지고 마지막 숫자를 알고 있다면 다음과 같은 변형을 고려할 수 있습니다.for n in $(seq -w 20 4 200); do cp "00802_..._00${n}" ...; done
Ulrich Schwarz

답변:


12

zsh를 사용하면 다음을 수행 할 수 있습니다.

n=0; cp 00802_Bla_Aquarium_?????.jpg(^e:'((n++%4))':) /some/place

POSIX 마찬가지로, 같은 생각, 조금 더 장황한 :

# put the file list in the positional parameters ($1, $2...).
# the files are sorted in alphanumeric order by the shell globbing
set -- 00802_Bla_Aquarium_?????.jpg

n=0
# loop through the files, increasing a counter at each iteration.
for i do
  # every 4th iteration, append the current file to the end of the list
  [ "$(($n % 4))" -eq 0 ] && set -- "$@" "$i"

  # and pop the current file from the head of the list
  shift
  n=$(($n + 1))
done

# now "$@" contains the files that have been appended.
cp -- "$@" /some/place

해당 파일 이름에는 공백 문자 나 와일드 카드 문자가 포함되어 있지 않으므로 다음을 수행 할 수도 있습니다.

cp $(printf '%s\n' 00802_Bla_Aquarium_?????.jpg | awk 'NR%4 == 1') /some/place

posix 코드에도 댓글을 달 수 있습니까
Rahul Patil

@ChrisDown for i do은 표준적이고 실제로 이식성이 뛰어나고 for i; do위치 매개 변수를 반복하는 정식 방법입니다.
Stéphane Chazelas

7

bash에서는 재미있는 가능성이 있습니다.

cp 00802_Bla_Aquarium_*{00..99..4}.jpg selected

그것은 가장 짧고 가장 효율적인 답입니다. 서브 쉘, 루프, 파이프, awk와드 외부 프로세스가 없습니다 . 하나의 포크 cp(어쨌든 피할 수 없음)와 하나의 bash 괄호 확장 및 glob (파일 수를 알고 있기 때문에 완전히 제거 할 수 있음).


4
… 그리고 2 개의 가정 : 파일은 연속적으로 번호가 매겨지고 첫 번째 파일은 4로 나눌 수 있습니다.
manatwork

@manatwork 첫 번째를 4로 나눌 수 없다면 아무 문제가 없습니다. 예를 들어, cp 00802_Bla_Aquarium_*{03..99..4}.jpg selected원하는 경우 3 mod 4. (100을 4로 나눌 수 있다는 놀라운 사실을 사용하고 있습니다). 이제 연속 번호가 매겨진 파일에 대해서는 다른 모든 대답이 동일하다고 가정합니다.
gniourf_gniourf

어떤 다른 답변이 연속 번호 매기기를 가정합니까? Ulrich Schwarz의 의견 만 찾았 으며 그러한 답변은 없었습니다.
manatwork

5

bash를 사용하면 다음을 수행 할 수 있습니다.

n=0
for file in ./*.jpg; do
   test $n -eq 0 && cp "$file" selected/
   n=$((n+1))
   n=$((n%4))
done

이 패턴 ./*.jpg은 bash man이 언급 한대로 알파벳순으로 정렬 된 파일 이름 목록으로 대체되므로 목적에 맞아야합니다.


bash에서는 for루프 내부의 세 줄을 다음 줄로 바꿀 수 있습니다 (((++n)%4)) || cp "$file" selected/. ;-). 문제는 비록 당신하는에있어 포크 (fork) cp에 대한 정말 효율적이지 않습니다 파일.
gniourf_gniourf

1

이 경우 ruby설치 한 다음 한 줄을 사용할 수 있습니다. 선택된 디렉토리가 존재한다고 가정합니다.

ruby -rfileutils -e 'files = Dir.glob("*.jpg").each_slice(4) { |file| FileUtils.cp(file.first, "selected/" + file.first) }'

현재 디렉토리에서 확장자가 .jpg 인 모든 파일의 목록을 가져 와서 네 개의 요소 목록으로 분할 한 다음 각 목록에서 첫 번째 요소를 현재 디렉토리에서 선택한 디렉토리로 복사합니다.


1

파일 이름에 줄 바꿈이 없다는 것을 알고 있다면 다음을 사용할 수 있습니다.

find . -maxdepth 1 -name "*.jpg" | sort | while IFS= read -r file; do
  cp "$file" selected/
  IFS= read -r; IFS= read -r; IFS= read -r
done

@Gilles : 편집 해 주셔서 감사합니다. 필요하지 않다는 것을 지적하기 위해 3 개의 읽기에서 파일 변수를 제거했습니다.
jfg956

1

GUI 파일 관리자를 사용하고 5 개의 파일이 한 행을 차지할 때까지 창의 테두리 크기를 조정 한 다음 마우스를 사용하여 첫 번째 열을 선택할 수 있습니다.


-1

@NN에서 언급했듯이 매 초마다 복사하는 솔루션을 제공하는 stackoverflow.com/q/4553751/789593을 보면 매우 간단한 솔루션은 다음과 같습니다.

  • 시작 폴더에서 첫 번째 파일을 제거
  • 시작 폴더에서 중간 폴더로 매 초마다 복사
  • 중간 폴더에서 최종 폴더로 1 초마다 복사
  • 첫 번째 파일을 수동으로 추가

추가 복사 단계 비트가 필요하기 때문에 매우 효율적이지 않을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.