首页 > 解决方案 > 如何编写 bash for 循环来创建模板

问题描述

如何编写 bash for 循环来创建模板

源文件:

    "INTEL SSDPEL1D380GA                   CCCCCCCCCCCCCCC    01",
    "Samsung SSD 970 PRO 1TB               XXXXXXXXXXXXXXX     01",
    "Samsung SSD 970 PRO 1TB               YYYYYYYYYYYYYYY     01",
    "Samsung SSD 970 PRO 1TB               ZZZZZZZZZZZZZZZ     01",
    "Samsung SSD 970 PRO 1TB               IIIIIIIIIIIIIII     01"

期望的输出:

node_nvme_device{manufacturer="INTEL",partnumber="SSDPEL1D380GA",serialnumber="CCCCCCCCCCCCCCC"} 1
node_nvme_device{manufacturer="Samsung",partnumber="SSD 970 PRO 1TB",serialnumber="XXXXXXXXXXXXXXX"} 1
node_nvme_device{manufacturer="Samsung",partnumber="SSD 970 PRO 1TB",serialnumber="YYYYYYYYYYYYYYY"} 1
node_nvme_device{manufacturer="Samsung",partnumber="SSD 970 PRO 1TB",serialnumber="ZZZZZZZZZZZZZZZ"} 1
node_nvme_device{manufacturer="Samsung",partnumber="SSD 970 PRO 1TB",serialnumber="IIIIIIIIIIIIIII"} 1

我尝试和失败的代码

awk 'NF>1 {
"node_nvme_device{manufacturer="$1",partnumber="$2",serialnumber="$3"} 1" }' source_file

标签: bashfor-loopawksedscripting

解决方案


可以使用单行程序,例如Perl,但使用 shell 脚本,您将拥有更多/更好的灵活性可伸缩性和代码维护,以供以后用例使用。

正确的解决方案将分为两个主要步骤:

  1. 首先将文件读入数组
  2. 将每一行读取为一个新数组

因此,对于第1部分,您可以使用mapfile内置的 bash 命令将您拥有的文件的所有行读入一个数组。

#!/bin/bash
mapfile -t arr < file.txt

现在您将拥有每行的数组,例如echo ${arr[0]}将打印您的第一行并echo ${arr[@]}打印所有行。然后您可以将每一行(步骤2)读入另一个数组并使用它们:

#!/bin/bash

# read all lines
mapfile -t arr < file.txt

# read just line 1
mapfile -t line1 < <(echo ${arr[0]} | tr ' ' '\n')

# print first element of line 1
echo ${line1[0]}

# output
"INTEL

然后您可以将这两个步骤重构为您自己的特定步骤。


请注意,您不必手动使用第二个mapfile(步骤2for-loop ),您可以使用 a来读取第一个数组(行数组),例如

for line in ${arr[@]}; do
    # read each line into an new array
    mapfile -t each_line < <(echo ${line[@]} | tr ' ' '\n');
     
    # do whatever you need to do with each line
    echo "each line: ${each_line[@]}";
done

另外,在使用内容/值之前,您应该删除文件中的额外字符,例如",,等。


推荐阅读