Bash에서 CSV 복사 스크립트 오류 보고

Bash에서 CSV 복사 스크립트 오류 보고

기본 폴더에서 csv에 나열된 파일을 재귀적으로 복사하는 스크립트가 있습니다. 스크립트의 복사 측면이 훌륭하게 작동합니다. 그러나 이제 몇 가지 오류 감지 기능을 추가하고 싶습니다. 아래에 추가한 "if" 루프가 원하는 대로 작동하지 않습니다. 테스트를 위해 csv 목록에 가짜 파일을 추가했는데 파일 중 하나가 존재하지 않는 경우에도 스크립트에서 모든 파일이 성공적으로 복사되었다고 보고합니다. csv에서 성공적으로 발견/복사되지 않은 파일을 보고하고 파일 이름을 지정하는 스크립트를 얻는 방법을 제안할 수 있는 사람이 있습니까? 편집** CSV에 4000개 이상의 파일이 나열되어 있으므로 스크립트가 프로세스 중에 복사된 각 파일에 대한 것이 아니라 스크립트 끝에 복사 실패에 대한 요약을 인쇄하고 싶습니다. 이렇게 하면 문제를 더 쉽게 식별/요약할 수 있습니다.

while IFS=, read -r file rest
do
find $sourcefolder -name "${file}" -exec cp '{}' $destfolder \;
done < $csv
if [ $? -eq 0 ]
then
echo "All files from CSV copied succesfully"
else "File from CSV not copied as not found"
fi

답변1

반환된 오류 코드는 find파일이 발견되었는지 여부와 관계가 없습니다. 명령 자체가 실행되지 않으면 단순히 실패 코드를 반환합니다. 당신이 찾고있는 것은 이것입니다 :

while IFS=, read -r file rest
do
  find $sourcefolder -name "${file}" -exec cp '{}' $destfolder \;
  ## Check if the file was copied
  [[ -e "$destfolder/$file" ]] || echo "File $file was not copied"
done < "$csv"
echo "Finished"

이렇게 하면 스크립트가 성공적으로 복사되지 않은 파일에 대해 알려줍니다.

스크립트 끝 부분에서만 오류를 인쇄하려면 오류 파일 이름을 변수에 저장하고 루프가 완료된 후 인쇄하면 됩니다.

while IFS=, read -r file rest
do
  find "$sourcefolder" -name "$file" -exec cp '{}' "$destfolder" \;
  ## Check if the file was copied
  [[ -e "$destfolder/$file" ]] || badfiles=$(printf "%s\n%s" "$file" "$badfiles")
done < "$csv"

## Check if all the files were correctly copied
if [[ -z "$badfiles" ]]; then
        echo "All files were succesfuly copied."
else
        printf 'Some files were not copied:\n%s\n' "$badfiles"
fi

동일한 이름의 파일을 덮어쓰지 않도록 확장할 수도 있습니다.

while IFS=, read -r file rest
do
  find "$sourcefolder" -name "$file" -print0 |
    while IFS= read -d '' -r filepath; do
     c="";
     while [[ -e "$destfolder/$file$c" ]]; do
       ((c++))
     done
     cp "$filepath" "$destfolder/$file$c"
  done
  ## Check if the file was copied
  [[ -e "$destfolder/$file" ]] || badfiles=$(printf "%s\n%s" "$file" "$badfiles")
done < "$csv"

## Check if all the files were correctly copied
if [[ -z "$badfiles" ]]; then
        echo "All files were succesfuly copied."
else
        printf 'Some files were not copied:\n%s\n' "$badfiles"
fi

csv의 파일 이름에 줄 바꿈이 포함될 수 있으면 이 작업이 실패합니다. 가능하다면 첫 번째 while루프를 다음과 같이 변경하세요.

while IFS= read -d"," -r file rest; do ...

그러나 csv의 행에 파일 이름만 포함되어 있으면(쉼표가 없음) 이 작업은 실패합니다. 두 가지 방법을 동시에 사용할 수 없습니다. 쉼표 없이 줄을 사용할 수 있으면 첫 번째 버전을 사용하고, 줄 바꿈이 있는 파일 이름을 가질 수 있으면 두 번째 버전을 사용하세요.

답변2

  1. 아무것도 하지 않기 때문에 루프가 올바르지 않습니다.rest

  2. ~처럼테든루프 이후에 한 번 확인하는 것보다 각 복사본 이후에 확인하는 것이 좋습니다.

  3. 올바른 주석을 얻기 위해 파일 검사의 존재를 무효화합니다.
  4. 그리고 참고특별한경고: 소스 트리에 동일한 이름을 가진 파일이 있는 경우 대상에는 하나의 복사본만 얻을 수 있습니다.

이 시도,

while read -d, -r file
do
   find $sourcefolder -name "${file}" -exec cp '{}' $destfolder \;
   ## Check if the file was copied
   [[ ! -e "$destfolder/$file" ]] && echo "File $file was not copied"
done < "$csv"
echo "Finished"

고쳐 쓰다:

이 솔루션은 CSV가 다음과 같은 경우에 작동합니다.

fileA,fileB,fileC,fileD, ...

하지만 terdon의 솔루션이 작동한다고 말했으므로 파일은 다음과 같아야 합니다.

fileA,valueA1,valueA2,valueA3
fileB,valueB1,valueB2,valueB3
fileC,valueC1,valueC2,valueC3
fileD,valueD1,valueC2,valueD3

파일 이름 뒤의 나머지 줄은 단순히 삭제됩니다.

관련 정보