소스 목록을 대상 목록으로 재동기화

소스 목록을 대상 목록으로 재동기화

편집하다: 제가 달성하려는 목표에 대한 더 깊은 이해를 돕기 위해 다음 예를 들어 보겠습니다. 팀의 일부는 폴더 구조가 좋지 않으며 이를 수정하는 것이 우리의 목표입니다.

원천:

/ShopA/Finances/Costs/contents
/ShopB/Finances/Costs/contents
/ShopC/Finances/Costs/contents

목적지:

/Finances/Costs/ShopA/contents
/Finances/Costs/ShopB/contents
/Finances/Costs/ShopC/contents

source.txt정확히 어떤 파일을 어떤 디렉토리에 복사해야 하는지에 대한 목록(파일 및 배열) 이 있는데 destination.txt, 수동으로 수행하지 않고도 소스 파일을 해당 대상에 복사하는 방법을 알아내는 것이 문제입니다. , 복사해야 할 파일이 수백 개가 있기 때문입니다.

소스 및 대상 목록은 한 줄씩 일치됩니다. 예를 들어, source.txt파일의 라인 1은 파일의 라인 1과 일치합니다 destination.txt.

나는 성공하지 않고 다음을 시도했습니다.

rsync -arv --files-from=/home/user/Desktop/source.txt / --files-from=/home/user/Desktop/destination.txt /

^목적지는 하나만 있을 수 있습니다.작동하지 않습니다.

for ((i = 0; i < ${#destination[@]}; i++)); do
    rsync -arv --files-from=/home/im-admin/Desktop/source.txt / "${destination[@]}"
done

^내가 잘못하고 있다는 것을 알고 있지만 각 소스 및 대상 폴더는 고유하므로 소스 파일 첫 번째 줄에서 대상 파일(또는 배열) 첫 번째 줄로 직접 파일을 복사하는 방법을 알아내는 데 도움이 필요합니다.

답변1

Bash에서 해당 요소 사이에 일대일 대응이 있는 정렬된 배열 쌍이 이미 있는 경우 루프를 사용하여 각 배열 쌍에 대해 명령을 실행하는 것은 매우 간단합니다.

for i in "${!sources[@]}"; do
    echo rsync -av -- "${sources[i]}" "${destinations[i]}"
done

( echo표시된 결과에 만족하면 삭제하여 파일을 실제로 복사하세요.)

배열 변수에 접두어를 적용하면 !해당 변수가 인덱스 목록으로 확장됩니다.

에 의해 암시되므로 -r옵션을 생략했습니다 .rsync-a

텍스트 파일에 저장된 경로 목록은 한 줄에 하나씩(물론 파일 경로에 개행 문자가 포함될 수 없다고 가정) 다음을 사용하여 배열로 읽을 수 있습니다.

mapfile -t surces <source.txt
mapfile -t destinations <destination.txt

mapfile(또는 이에 상응하는 readarray)은 표준 입력을 개행 문자(또는 이 옵션을 사용하여 명시적으로 지정된 구분 기호 -d)로 분할합니다. 이 -t옵션은 구분 기호 자체를 제거하도록 지시합니다. 그렇지 않으면 각 배열 요소의 마지막 문자로 유지됩니다.

관련 정보