서로 의존하는 두 개의 변수가 있는 For 루프를 사용하는 방법은 무엇입니까?

서로 의존하는 두 개의 변수가 있는 For 루프를 사용하는 방법은 무엇입니까?

100개의 .mp4 파일이 포함된 홈 디렉토리가 있습니다. 또한 dir_1, dir_2, dir_3최대 100개의 하위 디렉터리 세트가 있습니다 . 내가 원하는 것은 기본 디렉터리를 반복하여 .mp4 파일을 하위 폴더당 하나씩, 모든 하위 폴더에 배포하는 것입니다. 그런 다음 가능한 한 두 개의 루프 또는 두 개의 변수가 있는 하나의 루프가 있어야 합니다. 이것이 대략 한 줄의 코드로 달성하려는 목표입니다.

for file in *.mp4 & x in {1..100}; do mv $file dir_$x; done

답변1

set -- *.mp4

for dir in dir_*/; do
    mv -- "$1" "$dir"
    shift
done

모든 MP4 파일의 이름을 위치 인수 목록에 할당하는 것부터 시작하세요 set. 그런 다음 패턴과 일치하는 디렉터리를 반복합니다 dir_*/. 각 디렉토리에 대해 위치 매개변수 목록의 첫 번째 MP4 파일을 디렉토리로 이동한 다음 MP4 파일을 목록 밖으로 이동합니다.

위의 코드에는 MP4 파일만큼 많은 디렉터리가 있는지 확인하는 검사가 없습니다. 넌 그걸 원해 넌 할 수 있어

set -- *.mp4

for dir in dir_*/; do
    if [ "$#" -eq 0 ]; then
        echo 'Ran out of MP4 files' >&2
        exit 1
    fi
    mv -- "$1" "$dir"
done

if [ "$#" -ne 0 ]; then
    echo 'Too many MP4 files' >&2
    exit 1
fi

이 코드는 shPOSIX와 유사한 모든 셸에서 작동합니다.

답변2

산술 표현식을 사용하여 카운터를 증가시키려면 루프를 사용하십시오.

x=1
for file in *.mp4 ; do
    mv -- "$file" dir_$x/
    ((++x))
done

mp4 이름에는 공백이 포함될 수 있으므로 파일 이름을 큰따옴표로 묶습니다. 파일 이름이 대시로 시작하는 경우 --대시를 앞에 사용하면 "$file"파일 이름이 옵션 집합으로 해석되는 것을 방지할 수 있습니다.

답변3

또 다른 종류의 공격성:

#!/bin/bash

mp4=( ./*.mp4 )
for i in "${!mp4[@]}"
do
    mv "${mp4[i]}" "dir_$i/"
done

귀하의 경우에는 사용하지 않겠지만, 다양한 접근 방식을 보는 것은 항상 흥미롭습니다.

관련 정보