根据初始字符串变量组织多行文本,每三行或第二行

Organize multiple lines of text, every third or second line, depending on initial string variable

我有这样生成的行输出:

LINES=$(for i in {scsi,sat,ata,nvme}; do smartctl --scan -d $i ; done | sort | uniq | grep -v '^#|/dev/sd' | awk '{print,,}' | sed 's/,\r$//') ; while IFS= read -r line; do smartctl -i $line; done <<< "$LINES" | grep -v Family | grep -e Model -e Product: -e Vendor: -e "User Capacity" -e "Total NVM Capacity" | awk -F"[:\t]" '{print}'

给出以下输出:

           SEAGATE
          ST2000NX0273
    2,000,398,934,016 bytes [2.00 TB]
           SEAGATE
          ST2000NX0273
    2,000,398,934,016 bytes [2.00 TB]
           SEAGATE
          ST2000NX0273
    2,000,398,934,016 bytes [2.00 TB]
           SEAGATE
          ST2000NX0273
    2,000,398,934,016 bytes [2.00 TB]
           SEAGATE
          ST2000NX0273
    2,000,398,934,016 bytes [2.00 TB]
           SEAGATE
          ST2000NX0273
    2,000,398,934,016 bytes [2.00 TB]
 INTEL SSDSC2KB240G7
240,057,409,536 bytes [240 GB]
                   INTEL SSDPE2KX020T7
             2,000,398,934,016 [2.00 TB]
                   INTEL SSDPE2KX020T7
             2,000,398,934,016 [2.00 TB]

我希望将每个 HDD 信息放入其自己的行中,同时解析容量以显示其人类可读格式。如果 capacitt 仍然有 [brackets] 也没关系。期望的输出:

SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
INTEL SSDSC2KB240G7 240 GB
INTEL SSDPE2KX020T7 2.00 TB
INTEL SSDPE2KX020T7 2.00 TB

您能否尝试仅在 GNU awk.

中使用显示的示例进行跟踪、编写和测试
awk -v RS= -v FS="\n" '
{
  while([=10=]){
    match([=10=],/[^]]*/)
    val=""
    val=substr([=10=],RSTART,RLENGTH)
    gsub(/\n[[:space:]]+|\n/," ",val)
    sub(/^ +/,"",val)
    num=split(val,arr," |\[")
    print arr[1],arr[2],arr[num-1],arr[num]
    [=10=]=substr([=10=],RSTART+RLENGTH+1)
  }
}'  Input_file

解释:为以上添加详细解释。

awk -v RS= -v FS="\n" '                        ##Starting awk program from here and setting field separator as new line and RS as null.
{
  while([=11=]){                                   ##Running while loop till line exists.
    match([=11=],/[^]]*/)                          ##Using match function to match everything till ] here.
    val=""                                     ##Nullifying variable val here.
    val=substr([=11=],RSTART,RLENGTH)              ##Creating val which has sub-string from RSTART to till RLENGTH value.
    gsub(/\n[[:space:]]+|\n/," ",val)          ##Globally substituting either newline spaces OR only new lines with space in val.
    sub(/^ +/,"",val)                          ##Substituting starting spaces with NULL in val here.
    num=split(val,arr," |\[")                 ##Splitting val value into arr with deliminator of space and [ for all values.
    print arr[1],arr[2],arr[num-1],arr[num]    ##printing 1st, 2nd and 2nd last and last value of arr here.
   [=11=]=substr([=11=],RSTART+RLENGTH+1)              ##Re-creating value of current line which has REST of the line leaving part which was matched above, to skip already matched part and avoid duplicates.
  }
}'  Input_file                                 ##Mentioning Input_file name here.

如果你是运行这个命令,通过获取另一个命令的输出,然后像your_command | awk...一样将它通过管道传递给它们,你可以从上面删除Input_file。

awk -v RS=[][] '{ORS=(NR%2? " ": "\n"); print , }' file

正在使用您的输入进行测试:

> cat file
          SEAGATE
          ST2000NX0273
    2,000,398,934,016 bytes [2.00 TB]
           SEAGATE
          ST2000NX0273
    2,000,398,934,016 bytes [2.00 TB]
           SEAGATE
          ST2000NX0273
    2,000,398,934,016 bytes [2.00 TB]
           SEAGATE
          ST2000NX0273
    2,000,398,934,016 bytes [2.00 TB]
           SEAGATE
          ST2000NX0273
    2,000,398,934,016 bytes [2.00 TB]
           SEAGATE
          ST2000NX0273
    2,000,398,934,016 bytes [2.00 TB]
 INTEL SSDSC2KB240G7
240,057,409,536 bytes [240 GB]
                   INTEL SSDPE2KX020T7
             2,000,398,934,016 [2.00 TB]
                   INTEL SSDPE2KX020T7
             2,000,398,934,016 [2.00 TB]

输出:

SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
INTEL SSDSC2KB240G7 240 GB
INTEL SSDPE2KX020T7 2.00 TB
INTEL SSDPE2KX020T7 2.00 TB

此外,这里的初始方法是,] 是每个“记录”的结尾,应该是这样的:

awk -v RS=] '{gsub("\[",""); print , , $(NF-1), $NF}' file

在每个 Unix 机器上的任何 shell 中使用任何 awk:

$ cat tst.awk
gsub(/.*[[]|[]]/,"") {
    [=10=] = prev FS [=10=]
     = 
    print
    prev = ""
    next
}
{ prev = prev FS [=10=] }

.

$ awk -f tst.awk file
SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
SEAGATE ST2000NX0273 2.00 TB
INTEL SSDSC2KB240G7 240 GB
INTEL SSDPE2KX020T7 2.00 TB
INTEL SSDPE2KX020T7 2.00 TB