我正在尝试在ETL管道的一部分中在cloud-sdk Linux容器中运行bash脚本,基本上是在尝试使用gsutil
和sed
解决Cloud SQL导出MySql csv数据的方式问题(将null写入为怪异,未封闭的报价文件"N
,需要删除该文件后才能继续传输数据或对其进行解析。(对于Cloud SQL团队来说,这已经是一个公开问题,已有2年以上的历史了)。
该命令是
gsutil cp gs://bucket/dir/file.csv - | sed 's/"N,/,/g' | gsutil cp - gs://bucket/dir/file.csv
错误:
CommandException: cp: "gs://bucket/dir/file.csv" and "gs://bucket/dir/file.csv" are the same file - abort.
我也尝试过将管道分成两个步骤:
gsutil cp gs://bucket/dir/file.csv - | sed 's/"N,/,/g' > file.csv &&
gsutil cp file.csv gs://bucket/dir
但这也失败了,但有同样的错误,这对我来说毫无意义。第一个运行在CLI中完成,尽管将其添加到GCS的文件有0个字节。第二个命令在CLI中可以正常工作,但是在被Docker容器执行的bash命令调用时不会起作用。
我能想象的是,这两个命令是同时运行的,因此它们试图同时访问同一资源,但是操作顺序不应该是这种情况-除非为容器执行exec等待操作完成?
编辑:好吧,cp-是一个流处理过程,所以我认为可以将输入不断地传递到sed中,并且sed必须写在某个地方,所以sed必须将输入直接流回gcs,尽管更改了输出文件名不能解决错误。和2应该正常工作,除非&&之后的第二个命令在cp时执行-继续流式传输(在此处更改输出文件名也不能解决问题)。
最佳答案
您可以尝试将文件副本复制到另一个存储桶中:
gsutil cp gs:// [SOURCE_BUCKET_NAME] / [SOURCE_OBJECT_NAME] gs:// [DESTINATION_BUCKET_NAME] / [NAME_OF_COPY]
然后在文件中(在第二个存储桶中)进行更改:
sed's /“N,/,/ g” gs://bucket/dir/file.csv
然后只需删除旧文件并在第一个存储桶中移动新文件:
gsutil mv gs:// [SOURCE_BUCKET_NAME] / [SOURCE_OBJECT_NAME] gs:// [DESTINATION_BUCKET_NAME] / [DESTINATION_OBJECT_NAME]
这是一个较长的过程,但是您可以随时注意。
供您引用:https://cloud.google.com/storage/docs/renaming-copying-moving-objects
关于bash - gsutil cp管道在docker容器中作为bash exec命令失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62210017/