정의된 디렉터리 범위 내에서 명령을 실행합니다.

정의된 디렉터리 범위 내에서 명령을 실행합니다.

각 "범위"에서 서로 다른 작업을 수행하기 위해 디렉토리 목록을 특정 수의 청크로 "분할"할 수 있습니까?

예를 들어, 다른 폴더에 다음 디렉터리가 있다고 가정해 보겠습니다.

$ ls test
abc/
def/
hij/
klm/
nop/
qrs/
tuv/
wxy/
zzz/

처음 3개 디렉터리에 대해 일부 작업을 수행하고 마지막 3개 디렉터리에 대해 다른 작업 등을 수행하고 싶습니다.

비슷한 결과를 바탕으로 내 생각에는 숫자를 교차하는 루프가 작동할 수도 있습니다. (그러나 누군가 언급하기 전에 구문 분석은 절대 안 된다는 것을 ls | nl압니다 !)ls

이것은 분명히 작동하지 않을 것입니다. 그러나 제가 요점을 밝혔기를 바랍니다.

for dir in `ls | nl`; 
do
    do-something-with ${dir{1..3}} # Where $dir has taken on some numerical value linked to the folder)
    do-something-with ${dir{4..6}} 
# And so on...
    do-something-with ${dir{n-3..n}} 
done

실제로 이 작업을 수행하려는 폴더는 어떤 순서로든 처리할 수 있지만(즉, 최종 분할은 완전히 임의적일 수 있음) 논리적인 명명 일관성이 없습니다. 즉, 디렉터리 이름에 따라 알파벳순이나 숫자순으로 합리적으로 구성할 수 없다는 뜻입니다. 그 자체.

답변1

다음 중 하나를 수행할 이유가 없습니다.실수이 경우:

  1. 이식 불가능한 GNU 확장 사용(예 xargs -0: )
  2. 파일 이름만 텍스트 스트림으로 구문 분석하고 줄 바꿈을 포함할 수 없는 것처럼 가장합니다.

이 문제는 어려움 없이 쉽게 처리할 수 있습니다.

set -- */
while [ "$#" -gt 0 ]; do
  case "$#" in
    1)
      my-command "$1"
      shift 1
      ;;
    2)
      my-command "$1" "$2"
      shift 2
      ;;
    *)
      my-command "$1" "$2" "$3"
      shift 3
      ;;
  esac
done

실제로 이것은 필요 이상으로 장황하지만 이 방법으로 읽을 수 있습니다.

다양한 유형의 파티션에 대해 모든 디렉터리를 세 가지 다른 처리 방법으로 분할하려는 경우(그러나 동시에 처리할 필요는 없음) 다음을 수행할 수 있습니다.

x=1
for d in *; do
  [ ! -d "$d" ] && continue
  case "$x" in
    1)
      # do stuff with "$d"
      ;;
    2)
      # do stuff with "$d"
      ;;
    3)
      # do stuff with "$d"
      ;;
  esac
  x=$(($x+1))
  [ "$x" -eq 4 ] && x=1
done

답변2

그리고 printf/xargs:

printf "%s\0" */ | xargs -0 -n3 echo do-something
  • printf현재 디렉터리의 내용을 인쇄합니다(공백으로 구분). 후행 슬래시는 *파일이 아닌 디렉터리에만 일치합니다.
  • xargsNull로 구분된 입력 읽기-0
    • -n3입력을 3개 부분으로 나눕니다.

출력(예제 디렉터리 포함):

do-something abc/ def/ hij/
do-something klm/ nop/ qrs/
do-something tuv/ wxy/ zzz/

답변3

때로는 -n이를 위해 to 매개변수를 사용할 수 있습니다. xargs작업을 병렬로 실행하려는 경우에도 -P이 옵션을 사용할 수 있습니다 .

/tmp/t$ ls -1
dir1
dir2
dir3
dir4

/tmp/t$ ls -1 |xargs -n 3 echo runcmd
runcmd dir1 dir2 dir3
runcmd dir4

구문 분석된 출력에 대해 너무 걱정하지 마십시오 ls|nl. 이러한 사항에 대해 걱정해야 하는 경우 xargs find .. -print0매개변수를 사용할 수 있습니다 -0. (둘 다 사용 가능하다고 가정).

답변4

와일드카드의 솔루션은 내가 사용한 솔루션이므로 그의 답변을 승인된 것으로 표시했지만 나중에 이 문제를 우연히 발견하는 사람에게 유용할 경우를 대비하여 다른 11개 디렉터리 디렉터리 코드에 330을 균등하게 배포하는 방법은 다음과 같습니다. .

그것은 또한 매우 빠르게 보인다는 점을 지적할 가치가 있을 것입니다!

#!/bin/bash

numdirs=11

for ((i=1; i<=$numdirs; i++))
do
    mkdir -p ~/simulation_groups/group_${i}
done

x=1

for d in * ; do
  [ ! -d "$d" ] && continue
  case "$x" in
1)
  mv $d ~/simulation_groups/group_${x}
  ;;
2)
  mv $d ~/simulation_groups/group_${x}
  ;;
3)
  mv $d ~/simulation_groups/group_${x}
  ;;
4)
  mv $d ~/simulation_groups/group_${x}
  ;;
5)
  mv $d ~/simulation_groups/group_${x}
  ;;
6)
  mv $d ~/simulation_groups/group_${x}
  ;;
7)
  mv $d ~/simulation_groups/group_${x}
  ;;
8)
  mv $d ~/simulation_groups/group_${x}
  ;;
9)
  mv $d ~/simulation_groups/group_${x}
  ;;
10)
  mv $d ~/simulation_groups/group_${x}
  ;;
11)
  mv $d ~/simulation_groups/group_${x}
  ;;
  esac
  x=$(($x+1))
  [ "$x" -eq $numdirs+1 ] && x=1
done

관련 정보