azure - Azure存储目录列表的筛选结果

标签 azure azure-blob-storage azure-storage azure-cli

目标

有没有办法 (1) 下载 Azure 存储容器(目录、子目录、子子目录等)中名为 index.json 的每个文件,以及 (2) 使用源目录的名称重命名每个 index.json

建议的解决方案

我正在寻求一种解决方案,(1) 在 az CLI 中使用 az storage fs file download,(2) 应用通配符或模式来返回容器的每个目录级别中的每个 index.json,但我对 (2) 没有成功。请参阅下面的失败示例。

当前低效的解决方案

我当前的解决方案效率低下,并且不会从容器的所有级别返回 index.json - 仅返回顶层。

如果有帮助的话,我可以添加有关用例的详细信息。感谢您提供有关更好方法的任何帮助或想法。

Azure Blob 结构示例

container/

  product-1/
    articles/
      page-1.html
      page-2.html
    fonts/
      fontawesome.ttf
    images/
      product-image-1.png
      product-image-2.png
    node-modules/
      ...
    styles/
      style.css
      style.js
    index.html
    index.json

  product-2/
    articles/
      page-3.html
      page-4.html
    fonts/
      fontawesome.ttf
    images/
      product-image-3.png
      product-image-4.png
    node-modules/
      ...

    product-2-a/
      articles/
        page-3.html
        page-4.html
      fonts/
        fontawesome.ttf
      images/
        product-image-3.png
        product-image-4.png
      node-modules/
        ...
      styles/
        style.css
        style.js
      index.html
      index.json

    styles/
      style.css
      style.js
    index.html
    index.json

  index.html

期望的结果(本地计算机) - 每个 .json 文件都是重命名的 index.json 文件:

localIndexes/
  product-1.json
  product-2.json
  product-2-a.json

当前不可取的策略

  1. 创建一个 JSON 文件,该文件是 blob 中所有目录的列表(请注意,它不会下载子目录、下级子目录等,这是不需要的)。
az storage fs directory list -f wwwroot --recursive false --account-name $storageAccountName --account-key $accountKey > dirs.json

结果:dirs.json(不完整 - 仅包含对象的示例)

[
  {
    "contentLength": 0,
    "etag": "123",
    "group": "$abc",
    "isDirectory": true,
    "lastModified": "2022-01-13T23:20:19",
    "name": "product-1",
    "owner": "$abc",
    "permissions": "abc---"
  },
  {
    "contentLength": 0,
    "etag": "345",
    "group": "$abc",
    "isDirectory": true,
    "lastModified": "2022-01-13T23:20:19",
    "name": "product-2",
    "owner": "$abc",
    "permissions": "abc---"
  }
  {
    "contentLength": 0,
    "etag": "456",
    "group": "$abc",
    "isDirectory": true,
    "lastModified": "2022-01-13T23:20:19",
    "name": "styles",
    "owner": "$abc",
    "permissions": "abc---"
  }
]
  • 使用 jq 从 .name 中删除每个不需要的 dirs.json(也称为目录)的对象。使用我的低效方法,如果步骤 3 中的脚本遇到不包含 index.json 的目录,则会中断:
  • for excludeDir in css \
    fonts \
    images \
    js \
    node_modules \
    styles ; do
    jq --arg excludeDir $excludeDir '[.[] | select(.name != $excludeDir)]' dirs.json > temp.tmp && mv temp.tmp dirs.json
    done
    

    结果:dirs.json(不完整 - 仅包含对象的示例)

    [
      {
        "contentLength": 0,
        "etag": "123",
        "group": "$abc",
        "isDirectory": true,
        "lastModified": "2022-01-13T23:20:19",
        "name": "product-1",
        "owner": "$abc",
        "permissions": "abc---"
      },
      {
        "contentLength": 0,
        "etag": "345",
        "group": "$abc",
        "isDirectory": true,
        "lastModified": "2022-01-13T23:20:19",
        "name": "product-2",
        "owner": "$abc",
        "permissions": "abc---"
      }
    ]
    
  • 循环 .name 中的每个 dirs.json(又名目录),以 (1) 下载该目录中的 index.json 并 (2) 使用目录名称重命名 index.json
  • jq -r '.[] | "\(.name)"' dirs.json |
        while IFS="|" read -r name; do
    
    for dir in $name ; do
    blobName=`echo $name | tr -d '\r'`
    az storage blob download --container-name $containerName --file localIndexes/$blobName.json --name $blobName/index.json --account-key $accountKey --account-name $storageAccountName
    done
    
    done
    

    结果不完整

    请注意,product-2-a.json 丢失,进一步嵌套的子目录也丢失。

    localIndexes/
      product-1.json
      product-2.json
    

    尝试使用 az CLI 使用通配符/模式下载 index.json 失败

    各种迭代:

    az storage fs file download -p */index.json -f wwwroot --account-name $storageAccountName --account-key $accountKey
    
    az storage fs file download -p /**/index.json -f wwwroot --account-name $storageAccountName --account-key $accountKey
    
    az storage fs file download -p /--pattern index.json -f wwwroot --account-name $storageAccountName --account-key $accountKey
    
    

    最佳答案

    Azure 端没有特定的文件过滤器。我们需要获取所有文件,并且需要根据需求在客户端过滤文件。

    Azure 中上传的不同文件类型

    enter image description here

    使用 C# 和 Power shell 脚本从 azure 获取文件

    下面是用于获取文件的 Power shell 脚本

    enter image description here

    Install-Module Az.Storage
    Connect-AzAccount
    $MaxReturn = 20000
    $Container_Name = "container_Name"
    $Token = $Null
    $Storage_Context = New-AzureStorageContext -StorageAccountName 'storageaccount' -StorageAccountKey 'Key'
    $Container = Get-AzureStorageContainer -Name $Container_Name -Context $Storage_Context 
    $Blobs = Get-AzStorageBlob -Container $Container_Name -MaxCount $MaxReturn  -ContinuationToken $Token -Context $Storage_Context
    Echo $Blobs
    

    下面是使用C#代码过滤文件类型

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    foreach (var blob in blobs)
            {
                if (blob is CloudBlockBlob)
                {
                    var blob_FileName = blob.Uri.Segments.Last().Replace("%20", " ");
                    var blob_FilePath = blob.Uri.AbsolutePath.Replace(blob.Container.Uri.AbsolutePath + "/", "").Replace("%20", " ");
                    var blob_Path = blob_FilePath.Replace("/" + blob_FileName, "");
                    blob_Infos.Add(new BlobFileInfo
                    {
                        File = blob_FileName,
                        Path = blob_Path,
                        Blob_FilePath = blob_FilePath,
                        Blob = blob
                    });
                }
                if (blob is CloudBlobDirectory)
                {
                    var blob_Dir = blob.Uri.OriginalString.Replace(blob.Container.Uri.OriginalString + "/", "");
                    blob_Dir = blob_Dir.Remove(blob_Dir.Length - 1);
                    var subBlobs = ListFolderBlobs(containerName, blob_Dir);
                    blob_Infos.AddRange(subBlobs);
                }
            }
            return blob_Infos;
    

    关于azure - Azure存储目录列表的筛选结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74856277/

    相关文章:

    linux - Azure AKS 添加具有不同 Linux 操作系统的节点

    sql - Azure Blob 无法批量加载

    azure-storage - 如何查看Azure存储帐户队列

    iis - 在 Azure 中将应用程序池的标识设置为 LocalSystem

    azure - 无法创建集合信息 - 尝试在本地测试 Cosmos DB 触发器时出错

    azure 的 Blob - 几个大的或多个小的

    azure-blob-storage - 如何确保用户只能从私有(private) blob Azure 存储中看到属于他的图像?

    security - 为什么对 Azure Blob 存储使用 HTTPS

    azure - Microsoft.Samples.ServiceHosting.StorageClient 和 Microsoft.WindowsAzure.StorageClient 之间有什么区别

    azure - Umbraco7:在同一 Azure 存储帐户中设置多个/媒体/blob 容器