【问题标题】:Get `id` field from output of Openstack creation commands in shell script从 shell 脚本中 Openstack 创建命令的输出中获取 `id` 字段
【发布时间】:2017-01-12 11:21:10
【问题描述】:

OpenStack 命令(例如cinder createnova bootglance image-create)输出有关新卷/实例/映像的详细信息表。

$ cinder create --image 3896b01c-6afb-41a4-a207-3db87527be2c --display-name centos7-cloud 30
+---------------------+--------------------------------------+
|       Property      |                Value                 |
+---------------------+--------------------------------------+
|     attachments     |                  []                  |
|  availability_zone  |                 nova                 |
|       bootable      |                false                 |
|      created_at     |      2017-01-12T10:58:00.782361      |
| display_description |                 None                 |
|     display_name    |            centos7-cloud             |
|      encrypted      |                False                 |
|          id         | d1c6369b-73ce-498e-a2ef-2c6cea1d0f90 |
|       image_id      | 3896b01c-6afb-41a4-a207-3db87527be2c |
|       metadata      |                  {}                  |
|         size        |                  30                  |
|     snapshot_id     |                 None                 |
|     source_volid    |                 None                 |
|        status       |               creating               |
|     volume_type     |                 None                 |
+---------------------+--------------------------------------+

我正在创建一个 shell 脚本,其中下一个命令通过 id 引用新卷(在变量 CINDER_ID 中)。

nova boot --block-device source=volume,id=${CINDER_ID},dest=volume centos

id 提取到变量的最佳方法是什么?

【问题讨论】:

  • 为什么要删除 OpenStack 标签?这是 OpenStack CLI 的关键部分,我想知道是否有解决它的标准方法。
  • 您需要shell 的实用程序中的答案,在本例中为bash。因此,拥有其他人似乎并不合理。此外,理由是您将获得的任何帮助都将使用 shell 实用程序,因此最好单独保留这些标签。

标签: bash shell awk openstack


【解决方案1】:

以下解决方案使用支持环视的GNU grep

grep -owP 'id.*\|\s\K.*[^\|]+' inputfile
d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

要将其存储到变量中:

id=$(grep -owP 'id.*\|\s\K.*[^\|]+' inputfile)

你可以试试:

 id=$(cinder create --image 3896b01c-6afb-41a4-a207-3db87527be2c --display-name centos7-cloud 30 |grep -owP 'id.*\|\s\K.*[^\|]+' )

【讨论】:

  • 很好,-o-w\K 对我来说都是新的。
  • 由于某种原因,您的命令在grep (GNU grep) 2.26 上产生空输出。与文件中的 OP 表具有相同的文件
  • grep (GNU grep) 2.20 对我有用。来自文件和来自命令的管道。
  • 我的是sh-4.1$ grep --version GNU grep 2.6.3
【解决方案2】:

使用GNU awk'sgensub-function,您可以执行以下操作。以下逻辑中的函数从以| 分隔的列 2,3 中删除前导和尾随空格@

(通过将表写入文件进行检查)

awk -F"|" 'gensub(/^[ \t]+|[ \t]+$/,"","g",$2)=="id"{print gensub(/^[ \t]+|[ \t]+$/,"","g",$3);}' file
d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

要将其存储在变量中,

idValue="$(awk -F"|" 'gensub(/^[ \t]+|[ \t]+$/,"","g",$2)=="id"{print gensub(/^[ \t]+|[ \t]+$/,"","g",$3);}' file)"
printf "%s\n" "$idValue"
d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

您可以将生成上表的命令通过管道传递给 Awk

<your-command> | awk '{..}'

类似的,

cinder create --image 3896b01c-6afb-41a4-a207-3db87527be2c --display-name centos7-cloud 30 \
       | awk -F"|" 'gensub(/^[ \t]+|[ \t]+$/,"","g",$2)=="id"{print gensub(/^[ \t]+|[ \t]+$/,"","g",$3);}'
d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

【讨论】:

  • 谢谢,但我更喜欢上面更简洁的变体。
【解决方案3】:

您可以使用\s*\|\s* 作为字段分隔符

CINDER_ID=$(cinder create --image 3896b01c-6afb-41a4-a207-3db87527be2c --display-name centos7-cloud 30 |
awk 'BEGIN{FS="\\s*\\|\\s*"}$2=="id"{print $3}')
echo $CINDER_ID

你得到

d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

【讨论】:

  • 谢谢,简洁明了。
【解决方案4】:

我想出的另一种选择是sed

sed -n 's/|\s*id\s*|\s*\(.*\S\)\s*|/\1/p' inputfile
d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

存储在变量中,

CINDER_ID=$(cinder create --image 3896b01c-6afb-41a4-a207-3db87527be2c \
--display-name centos7-cloud 30 | sed -n 's/|\s*id\s*|\s*\(.*[^\s]\)\s*|/\1/p' )

echo $CINDER_ID
d1c6369b-73ce-498e-a2ef-2c6cea1d0f90

【讨论】:

    【解决方案5】:

    鉴于列值被空格包围(除了| 列分隔符),awk 的默认字段拆分行为会这样做| 实例然后简单地算作自己的字段):

    cinder_ID=$(cinder create ... | awk '$2=="id" {print $4}')
    

    您可以在块内附加; exit 以立即停止处理;但是,对于这么小的输入集可能不值得。

    请注意,我已将您的变量名从 CINDER_ID 更改为 cinder_ID,因为 最好不要使用全大写的 shell 变量名,以便 avoid conflicts with environment variables and special shell variables

    【讨论】:

      【解决方案6】:

      我认为您在这里不需要任何 Fancy 正则表达式匹配。在您创建了一个具有某个名称的图像后,您可以发出此命令来获取图像 ID。

      # openstack image list -f value | grep '<Image name>' | awk '{print $1}'
      

      你可以对音量做同样的事情。

      # openstack volume list -f value | grep '<volumename>' | awk '{print $1}'
      

      【讨论】:

      • 这仅适用于名称唯一的情况。我不能保证。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-06
      • 1970-01-01
      • 2022-08-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多