0

I am trying to grab results from lshw and add them to a a bash array so I can create a new string. I am using

lshw -class disk |egrep -A 7 .'-d' |grep 'product' |cut -b 17-

the output looks like this

Samsung SSD 850
Samsung SSD 840
ST8000AS0002-1NA
ST8000AS0002-1NA
Samsung SSD 870
Samsung SSD 870
ST8000VN0022-2EL
Flash Drive FIT
Flash Drive FIT
ST8000AS0002-1NA
ST8000VN0022-2EL
Samsung SSD 870
Samsung SSD 870
ST8000VN004-2M21

I tried to add this output to a bash array but each line with words separated by a space becomes an element in the array. You can also see the results from this command

for w in $(lshw -class disk |egrep -A 7 .'-d' |grep 'product' |cut -b 17-); do printf "$w \n" ;done

output

Samsung
SSD
850
Samsung
SSD
840
ST8000AS0002-1NA
ST8000AS0002-1NA
Samsung
SSD
870
Samsung
SSD
870
ST8000VN0022-2EL
Flash
Drive
FIT
Flash
Drive
FIT
ST8000AS0002-1NA
ST8000VN0022-2EL
Samsung
SSD
870
Samsung
SSD
870
ST8000VN004-2M21

How can I can I keep space separated lines as one one string?

2
  • That looks like a pretty fragile way of parsing the output of lshw - I'd suggest using its JSON output format with jq to extract the information, something like lshw -class disk -json | jq -r 'select(.id == "disk") | .product' Commented Apr 20, 2022 at 15:24
  • I don’t understand what result you want. You say “each line with words separated by a space becomes an element in the array” in a context that suggests that that’s what’s happening and it’s not what you want, but you also don’t seem individual words to be elements. Do you want the entire 30-word string to be a single element? If so, why are you trying to use an array? … … … … … … … … Please do not respond in comments; edit your question to make it clearer and more complete. Commented Apr 21, 2022 at 5:52

2 Answers 2

1

mapfile may be easiest.

mapfile -t myarray < <(lshw -class disk |egrep -A 7 .'-d' |grep 'product' |cut -b 17-)

But if you don't want to use a literal array and just want a loop over the results, you can just do:

lshw -class disk |egrep -A 7 .'-d' |grep 'product' |cut -b 17- | while read w ; do [something with w] ; done
0

Quote the command substitution:

# for w in "$(lshw -class disk |egrep -A 7 .'-d' |grep 'product' |cut -b 17-)"; do printf "$w \n" ;done
USB3.0 DISK00               
USB3.0 DISK01
USB3.0 DISK02
MS/MS-Pro
SD/MMC
Compact Flash
SM/xD-Picture
ST1000DM003-1CH1
WDC WD20EZAZ-00G

You then get: "USB3.0 DISK00" "USB3.0 DISK01" ... being passed into the for loop.

2
  • 1
    That actually passes everything as a single multi-line string I think? See for example bash pitfall #1 Commented Apr 20, 2022 at 17:56
  • I'll be honest, I'd have never set it up that way, I just supplied a fix. It works, as the example shows. I haven't done any debugging though and it may be a one multi-line string rather that a number of discrete lines. If I was doing for myself I'd pipe the output from the lshw into AWK and deal with it there, but then I'm old-fashioned! Frabjous' second example is a better solution. Commented Apr 20, 2022 at 19:36

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.