求助:按最后修改日期从S3下载文件到本地失败
下载S3存储桶中特定修改日期文件的问题解决
需求
将S3存储桶中特定日期修改的文件下载到本地路径,尝试以下命令均失败:
aws s3 cp $S3_SOURCE_FILE_ARCH_DIR/ $EMR_EDGE_NODE_SRC_FILE_ARCH_DIR/ --recursive --exclude "*" --include "20230719*.*" --include "20230720*.*" aws s3api list-objects --bucket $S3_SOURCE_FILE_ARCH_DIR --output text --query "Contents[?LastModified = `2022-09-28`].{Key:Key)}" aws s3 cp $S3_SOURCE_FILE_ARCH_DIR/ $(aws s3api list-objects-v2 --bucket $S3_SOURCE_FILE_ARCH_DIR/ --output text --query "Contents[?LastModified>=='2022-09-28'].{Key: Key}") $EMR_EDGE_NODE_SRC_FILE_ARCH_DIR/ aws s3 ls $S3_SOURCE_FILE_ARCH_DIR/ --recursive | awk '/^2022-09-28/{system("aws s3 cp $EMR_EDGE_NODE_SRC_FILE_ARCH_DIR/" $4 " .")}' content=$(aws s3api list-objects-v2 --bucket $S3_SOURCE_FILE_ARCH_DIR/ --query 'Contents[?contains(LastModified, `2022-09-28`)]' | jq -r ".[].Key") for file in $content; do aws s3api copy-object --copy-source $S3_SOURCE_FILE_ARCH_DIR/$file --key $file --bucket $EMR_EDGE_NODE_SRC_FILE_ARCH_DIR/ | jq done
错误原因分析
- 第一条命令:
--include匹配的是文件名而非修改日期,20230719*.*是按文件名前缀筛选,只会下载文件名以该日期开头的文件,无法匹配修改日期为当天的文件。 - 第二条命令:
LastModified的格式是带时间戳的完整UTC格式(如2022-09-28T12:34:56Z),直接等于2022-09-28不会匹配任何结果;同时查询语法错误,Key:Key)}多了一个右括号。 - 第三条命令:
list-objects-v2的--bucket参数仅需桶名,不能带路径后缀;且aws s3 cp无法直接处理list-objects输出的多行文本,参数传递逻辑错误。 - 第四条命令:单引号内的变量
$EMR_EDGE_NODE_SRC_FILE_ARCH_DIR不会被Shell解析,且aws s3 cp的路径顺序写反了,应该是S3路径在前,本地路径在后。 - 第五条命令:
copy-object是用于S3桶之间的复制操作,不能下载到本地;且--bucket参数同样不能带路径,变量解析逻辑有误。
正确解决方案
方法1:用s3api筛选+循环下载(推荐)
通过list-objects-v2精准筛选指定日期范围的文件,再循环下载到本地:
# 定义UTC时间范围(以2022-09-28当天为例) START_DATE="2022-09-28T00:00:00Z" END_DATE="2022-09-29T00:00:00Z" BUCKET_NAME="你的S3桶名" BUCKET_PREFIX="桶内路径前缀(可选,无则留空)" # 获取符合条件的文件Key列表 FILES=$(aws s3api list-objects-v2 --bucket $BUCKET_NAME --prefix $BUCKET_PREFIX/ \ --query "Contents[?LastModified >= '$START_DATE' && LastModified < '$END_DATE'].Key" \ --output text) # 循环下载每个文件到本地路径 for FILE in $FILES; do aws s3 cp s3://$BUCKET_NAME/$FILE $EMR_EDGE_NODE_SRC_FILE_ARCH_DIR/$(basename $FILE) done
方法2:用s3 ls结合awk筛选
利用aws s3 ls的输出格式,通过awk匹配日期后下载:
BUCKET_PATH="s3://你的S3桶名/桶内路径前缀" aws s3 ls $BUCKET_PATH --recursive | \ awk '/^2022-09-28/{print $4}' | \ while read FILE; do aws s3 cp s3://你的S3桶名/$FILE $EMR_EDGE_NODE_SRC_FILE_ARCH_DIR/ done
注意事项
- 替换示例中的
你的S3桶名和桶内路径前缀为实际值。 LastModified为UTC时间,若需匹配本地时区,需先做时间转换。- 文件数量较多时,建议添加错误判断(如检查
aws命令执行状态),避免中断。
内容的提问来源于stack exchange,提问作者melinda soto
相关产品推荐
相关产品推荐

