각 "범위"에서 서로 다른 작업을 수행하기 위해 디렉토리 목록을 특정 수의 청크로 "분할"할 수 있습니까?
예를 들어, 다른 폴더에 다음 디렉터리가 있다고 가정해 보겠습니다.
$ 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
다음 중 하나를 수행할 이유가 없습니다.실수이 경우:
- 이식 불가능한 GNU 확장 사용(예
xargs -0
: ) - 파일 이름만 텍스트 스트림으로 구문 분석하고 줄 바꿈을 포함할 수 없는 것처럼 가장합니다.
이 문제는 어려움 없이 쉽게 처리할 수 있습니다.
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
현재 디렉터리의 내용을 인쇄합니다(공백으로 구분). 후행 슬래시는*
파일이 아닌 디렉터리에만 일치합니다.xargs
Null로 구분된 입력 읽기-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