

# 将 Amazon S3 库存报告中的空版本 ID 字符串转换为空字符串
<a name="inventory-configure-bops"></a>

**注意**  
**下面的过程只适用于包含所有版本的 Amazon S3 库存报告，并且只有当"所有版本"的报告作为 S3 分批操作在已启用 S3 版本的存储桶上的显示时才适用。**您无需为仅指定当前版本的 S3 清单报告转换字符串。

您可以使用 S3 清单报告作为 S3 分批操作的清单。但是，在存储桶上启用 S3 版本控制时，包括所有版本的 S3 清单报告将在版本 ID 字段中用空字符串标记任何空版本控制的对象。当库存报告包含所有对象版本 ID 时，分批操作将 `null` 字符串识别为版本 ID，但不是空字符串。

当 S3 分批操作任务使用“所有版本”S3 清单报告作为清单时，它会使版本 ID 字段中有空字符串的对象上的所有任务失败。要将 S3 库存报告版本 ID 字段中的空字符串转换为分批操作 `null` 字符串，使用以下过程。

**更新 Amazon S3 库存报告以便与分批操作一起使用**

1. 登录到 Amazon Web Services 管理控制台，然后通过以下网址打开 Amazon S3 控制台：[https://console.aws.amazon.com/s3/](https://console.amazonaws.cn/s3/)。

1. 导航至 S3 清单报告。库存报告位于您在配置库存报告时指定的目标存储桶中。有关查找清单报告的更多信息，请参阅 [查找清单列表](storage-inventory-location.md)。

   1. 选择目标存储桶。

   1. 选择 文件夹。该文件夹以原始源存储桶命名。

   1. 选择以清单配置命名的文件夹。

   1. 选择名为 **hive** 的文件夹旁边的勾选框。在页面顶部，选择 **Copy S3 URI**（复制 S3 URI）以为文件夹复制 S3 URI。

1. 从 [https://console.aws.amazon.com/athena/](https://console.amazonaws.cn/athena/home) 打开 Amazon Athena 控制台。

1. 在查询编辑器中，选择 **Settings**（设置），然后选择 **Manage**（管理）。在存储库的 **Manage settings**（管理设置）页面中，针对 **Location of query result**（查询结果的位置），选择用于存储查询结果的 S3 存储桶。

1. 在查询编辑器中，使用以下命令创建 Athena 表以保存库存报告中的数据。将 `{{table_name}}` 替换为您所选择的名称，然后在 `LOCATION` 子句中，插入之前复制的 S3 URI。然后选择 **Run**（运行），以运行查询。

   ```
   CREATE EXTERNAL TABLE {{table_name}}(bucket string, key string, version_id string) PARTITIONED BY (dt string)ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.SymlinkTextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.IgnoreKeyTextOutputFormat' LOCATION '{{Copied S3 URI}}';
   ```

1. 要清除查询编辑器，请选择 **Clear**（清除）。然后使用以下命令将清单报告加载到表中。将 `{{table_name}}` 替换为您在上一步所选择的项。然后选择 **Run**（运行），以运行查询。

   ```
   MSCK REPAIR TABLE {{table_name}};
   ```

1. 要清除查询编辑器，请选择 **Clear**（清除）。运行以下 `SELECT` 查询以检索原始库存报告中的所有条目，并将任何空版本 ID 替换为 `null` 字符串。将 `{{table_name}}` 替换为先前所选择的项，然后将 `WHERE` 子句中的 `{{YYYY-MM-DD-HH-MM}}` 替换为您想要此工具运行的库存报告的日期。然后选择 **Run**（运行），以运行查询。

   ```
   SELECT bucket as Bucket, key as Key, CASE WHEN version_id = '' THEN 'null' ELSE version_id END as VersionId FROM {{table_name}} WHERE dt = '{{YYYY-MM-DD-HH-MM}}';
   ```

1. 返回 Amazon S3 控制台 ([https://console.aws.amazon.com/s3/](https://console.amazonaws.cn/s3/))，然后导航到稍早您为 **Location of query result**（查询结果位置）选择的 S3 存储桶。其内部应该有一系列以日期结束的文件夹。

   例如，您将看到类似于 **s3://{{{{amzn-s3-demo-bucket}}}}/{{query-result-location}}/Unsaved/2021/10/07/** 的内容。您将看到包含您运行的 `SELECT` 查询的结果的 `.csv` 文件。

   选择具有最新修改日期的 CSV 文件。将此文件下载到本地计算机以进行下一步。

1. 生成的 CSV 文件包含标题行。要使用此 CSV 文件作为 S3 分批操作任务的输入，您必须移除标题行，因为分批操作不支持 CSV 清单上的标题行。

   要移除标题行，可以对文件运行以下命令之一。将 {{`file.csv`}} 替换为 CSV 文件的名称。

   **对于 macOS 和 Linux 计算机**，在终端窗口运行 `tail` 命令。

   ```
   tail -n +2 {{file.csv}} > tmp.csv && mv tmp.csv {{file.csv}} 
   ```

   **对于 Windows 计算机**，在 Windows PowerShell 窗口中运行以下脚本。将 `{{File-location}}` 替换为文件的路径，将 `{{file.csv}}` 替换为文件名。

   ```
   $ins = New-Object System.IO.StreamReader {{File-location}}\{{file.csv}}
   $outs = New-Object System.IO.StreamWriter {{File-location}}\temp.csv
   try {
       $skip = 0
       while ( !$ins.EndOfStream ) {
           $line = $ins.ReadLine();
           if ( $skip -ne 0 ) {
               $outs.WriteLine($line);
           } else {
               $skip = 1
           }
       }
   } finally {
       $outs.Close();
       $ins.Close();
   }
   Move-Item {{File-location}}\temp.csv {{File-location}}\{{file.csv}} -Force
   ```

1. 从 CSV 文件中移除标题行后，您可以在 S3 分批操作任务中将其用作清单。将 CSV 文件上载到 S3 存储桶或您选择的位置，然后使用 CSV 文件作为清单创建分批操作任务。

   有关创建 S3 分批操作任务的更多信息，请参阅 [创建 S3 批量操作任务](batch-ops-create-job.md)。