微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决如何编写 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",serialnumber="YYYYYYYYYYYYYYY"} 1
node_nvme_device{manufacturer="Samsung",serialnumber="ZZZZZZZZZZZZZZZ"} 1
node_nvme_device{manufacturer="Samsung",serialnumber="IIIIIIIIIIIIIII"} 1

我尝试和失败的代码

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

解决方法

可以使用单线,例如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(步骤 2),您可以使用 for-loop 来读取第一个数组(行数组),例如

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

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

,

仅使用您显示的示例,请尝试以下操作。

awk '
match($0,/".*               /){
  val1=""
  val=substr($0,RSTART+1,RLENGTH-1)
  sub(/[[:space:]]+$/,"",val)
  num=split(val,arr," ")
  for(i=2;i<=num;i++){
    val1=(val1?val1 OFS:"")arr[i]
  }
  printf("node_nvme_device{manufacturer=\"%s\",partnumber=\"%s\",serialnumber=\"%s\"} %01d\n",arr[1],val1,$(NF-1),$NF)
}' Input_file

说明: 简单地使用awk的匹配函数按照显示的样本从开始到更大的空间进行匹配,然后将其匹配的子字符串保存到val中,删除空格以摆脱它,然后创建 val2 ,它具有从第二个元素到数组末尾的所有值(因为 OP eg--> SSD 970 PRO 1TB 在此处匹配的样本中有多个值),然后最后使用 printf 根据需要的输出打印值,只需传递值(当前行的字段和数组元素的 val1 值在这里)。

,

这是另一种 awk 替代方案:

awk '
{
   mf = $1
   sn = $(NF-1)
   gsub(/^[[:blank:]]*"[^[:blank:]]+[[:blank:]]+|[[:blank:]]{2,}[[:alnum:]].*$/,"")
   printf "node_nvme_device{manufacturer=%s\",serialnumber=\"%s\"} 1\n",mf,$0,sn
}' file

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",serialnumber="YYYYYYYYYYYYYYY"} 1
node_nvme_device{manufacturer="Samsung",serialnumber="ZZZZZZZZZZZZZZZ"} 1
node_nvme_device{manufacturer="Samsung",serialnumber="IIIIIIIIIIIIIII"} 1
,

假设数据以制表符分隔并使用 Python:

#!/usr/bin/python
for f in open("parts"):                                # Open a file called parts
   f=f.replace("\"","")                                # Remove quotes from the line
   f=f.replace(",","")                                 # Remove commas from the line
   bits=f.split("\t")                                  # Split the line into the array bits based on tabs
   bits1=bits[0].split(" ")                            # Split the first index further into bits1 this time using " "
   stryng=bits1[0]
   numb=int(bits[2])
   for i in range(1,len(bits1),1):                     # Loop through bit1,building a strinf stryng
      stryng=stryng + " " + bits1[i]
   print("node_nvme_device{manufacturer=\"" + bits1[0] + "\",partnumber=\"" + stryng + "\",serialnumber=\"" + bits[1] + "\"} " + str(numb))       # Print the data in format required

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。