デフォルトのフォルダから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つの方法を同時に使用することはできません。カンマなしで行を使用できる場合は最初のバージョンを使用し、改行のあるファイル名を持つことができる場合は2番目のバージョンを使用してください。
答え2
何もしないので、ループが正しくありません。
rest
〜のようにテデンループの後に一度チェックするよりも、各コピーの後にチェックすることをお勧めします。
- 正しいコメントを得るためにファイルチェックの存在を無効にします。
- そして参考特別な警告:ソースツリーに同じ名前のファイルがある場合、ターゲットには1つのコピーしか取得できません。
この試み、
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
ファイル名の後の残りの行は単に削除されます。