두 디렉터리([A/{a,b,c}] 및 [n/{1,2,3}]를 동시에 반복하여 내용과 쌍을 형성하는 방법)

두 디렉터리([A/{a,b,c}] 및 [n/{1,2,3}]를 동시에 반복하여 내용과 쌍을 형성하는 방법)

이걸 어떻게 찾아야 할지 모르겠으니, 어딘가에 있다면 답을 알려주세요. 또한 질문 제목이 불분명하고 더 나은 설명이 생각나지 않는 경우 미리 사과드리고 싶습니다.

다음은 제가 하려는 작업에 대한 간단한 예입니다. 서로 다른 하드 드라이브에 다음 두 디렉터리가 있다고 가정해 보겠습니다.

A/data_dir1/포함하다:

  • dir1/
  • dir2/
  • dir3/
  • dir4/

B/info_dir1/포함하다:

  • dirA/
  • dirB/
  • dirC/
  • dirD/

이제 알파벳순으로 정렬하면 dir1/과 dirA/가 관련되어 있으므로 dir1/에서 일부 파일을 추출하여 dirA/에 복사하려고 합니다. dir2/ 및 dirB/, dir3/ 및 dirC/ 등에서도 동일한 일이 발생합니다.

이 작업을 수행하는 더 쉽고, 더 좋고, 더 정확하고, 더 빠른 방법이 있다고 확신하지만 지금은 이 아이디어에 갇혀 있고 다른 방법을 생각할 수 없으므로 다음을 수행하고 싶습니다.

counter1=0
for info_dir in $(ls -d info_dir1/*); do
    counter1=counter1+1
    counter2=0
    for data_dir in $(ls -d data_dir1/*); do
        counter2=counter2+1
        if [[ counter1 == counter2 ]]; then
            cp $data_dir/[file2copy] $info_dir/
        fi
    done
done

항상 두 폴더를 올바른 순서로 반복한다는 가정 하에 이렇게 하고 있는데 혹시 문제가 생길까 걱정됩니다. 내가 간과하고 있는 다른 방법이 있나요?

귀하가 제공할 수 있는 도움에 진심으로 감사드립니다!

답변1

각각 디렉터리 집합에 해당하는 두 개의 배열을 만든 다음 인덱스를 반복합니다.

data_dirs=( A/data_dir1/*/ )
info_dirs=( B/info_dir1/*/ )
n=${#data_dirs[@]}               # assume they're the same length
for (( i = 0; i < n; i++ )); do
    left="${data_dirs[i]}"
    right="${info_dirs[i]}"
    printf "%s <-> %s\n" "$left" "$right"
    # or whatever
done

쉘은 glob의 파일 이름을 사전순으로 정렬하므로 ; dirA와 쌍을 이루어야 합니다 dir1. 등과 dirB짝을 이루었습니다 dir2. 하지만 다시 확인해 보는 것이 가장 좋습니다. 그럴 필요는 없습니다 ls. 이는 쉘에서 제공하는 파일 이름 목록에 아무것도 추가하지 않는 추가 프로세스일 뿐입니다. (또한 공백이 포함된 파일 이름이 손상됩니다.)

"튜플 스타일"과 "[A/an/1] [A/bn/2]" 구문이 무엇을 의미하는지 모르겠습니다.

답변2

디렉터리 구조가 주어지면 필수 디렉터리 이름 쌍을 생성하는 몇 가지 방법은 다음과 같습니다.

for info_dir in info_dir1/*/; do read data_dir; echo "$data_dir" "$info_dir"; done <<< $(ls -1d data_dir1/*/)
data_dir1/dir1/ info_dir1/dirA/
data_dir1/dir2/ info_dir1/dirB/
data_dir1/dir3/ info_dir1/dirC/
data_dir1/dir4/ info_dir1/dirD/

또는

paste <(ls -1d data_dir1/*/) <(ls -1d info_dir1/*/)
data_dir1/dir1/ info_dir1/dirA/
data_dir1/dir2/ info_dir1/dirB/
data_dir1/dir3/ info_dir1/dirC/
data_dir1/dir4/ info_dir1/dirD/

또는

{ ls -d data_dir1/*/; ls -d info_dir1/*/; } | \pr -2ts" " -
data_dir1/dir1/ info_dir1/dirA/
data_dir1/dir2/ info_dir1/dirB/
data_dir1/dir3/ info_dir1/dirC/
data_dir1/dir4/ info_dir1/dirD/

답변3

존재하다 zsh:

data_dirs=( A/data_dir1/*(Nn/) )
info_dirs=( B/info_dir1/*(Nn/) )
for data info in ${data_dirs:^info_dirs}; do
  something with $data and $info
done

어디:

  • 예를 들어, glob 한정자는 n일반적으로 어휘 정렬된 glob에서 수행되는 것처럼 and 사이가 아닌 and 뒤에 정렬할 수 있습니다.numericglobsortdir10dir9dir1dir2
  • /파일 형식 제한목차. -/디렉토리에 대한 심볼릭 링크도 고려하려면 로 변경하세요.
  • ${A:^B}2개의 배열을 압축합니다. 크기가 다른 경우 가장 긴 크기가 가장 짧은 크기로 잘립니다. 예를 들어, (a b c)zipped를 사용 (1 2)하면 (a 1 b 2).
  • 에서는 zsh여러 변수를 사용하여 반복할 수 있으므로 for i j in a 1 b 2먼저 i=aj=1로 반복한 다음 i=bj=2로 반복합니다.

관련 정보