I'm working on a one-liner to get the PCI Address of GPUs from Incus. Here is the output of the first part of the command:
incus info --resources | grep -E 'GPU:|GPUs:' -A 20
GPUs:
Card 0:
NUMA node: 0
Vendor: ASPEED Technology, Inc. (1a03)
Product: ASPEED Graphics Family (2000)
PCI address: 0000:22:00.0
Driver: ast (6.12.9-production+truenas)
DRM:
ID: 0
Card: card0 (226:0)
Control: controlD64 (226:0)
Card 1:
NUMA node: 0
Vendor: NVIDIA Corporation (10de)
Product: GP102 [GeForce GTX 1080 Ti] (1b06)
PCI address: 0000:2b:00.0
Driver: nvidia (550.142)
DRM:
ID: 1
Card: card1 (226:1)
Render: renderD128 (226:128)
NVIDIA information:
Architecture: 6.1
Brand: GeForce
Model: NVIDIA GeForce GTX 1080 Ti
CUDA Version: 12.4
NVRM Version: 550.142
UUID: GPU-9d45b825-9a28-afab-1189-e071779f7469
I'm using grep to limit it to 'amd|intel|nvidia', awk to print the PCI Address:, then sed to remove the whitespaces. I keep getting a trailing hash (#) char which is actually generated from the printf. printf is removing all the additional newlines automatically for me. However, I haven't found a way to nix the hash char. What am I missing here? If there is a better way to do this I'm open to that as well. Thank you!
incus info --resources | grep -E 'GPU:|GPUs:' -A 20 | grep -Ei 'amd|intel|nvidia' -A 20 | awk -F "PCI address:" '{printf $2}' | sed 's/ //'
0000:2b:00.0#
Edit: In short and to add some clarity, I just need to grab the PCI Address: from one of amd, intel, or nvidia and output the PCI Address: only.
This might be what you're trying to do, using any POSIX awk:
$ awk '
/^[^[:space:]]/ { g = (/GPUs?:/) }
/Vendor:/ { v = (tolower($0) ~ /amd|intel|nvidia/) }
g && v && sub(/.*PCI address: /,"")
' file
0000:2b:00.0
You don't need the | grep -E 'GPU:|GPUs:' -A 20, nor any call to sed or any other tool. If the above doesn't do exactly what you want then edit your question to clarify your requirements and/or provide more truly representative sample input/output.
By the way, regarding printf $2 from the OPs code in the question - only do printf $2 (for any input string) if you have a VERY specific and highly unusual need to interpret input as printf formatting strings, otherwise use printf "%s", $2 so it won't fail when the input contains printf formatting strings like %s.
This might work for you (GNU sed):
sed -nE '/^\S/{h;d}
x;/^GPUs?:/ba;x;d
:a;x;/^\s*Vendor:/{x;s/\n.*//;x;H;d}
x;/^GPUs?:\n\s*Vendor:.*(amd|intel|nvidia)/Ibb;x;d
:b;x;s/.*PCI address: //p' file
If a line contains PCI address: print the remainder of that line if and only if the lines preceding it also contained the string GPUs: and Vendor: with the vendor being either amd, intel or nvidia.
An alternative:
sed -En ':a;/^GPUs?/!b
:b;n;/^\S/ba;/^\s*Vendor:/!bb
:c;/amd|intel|nvidia/I!bb
:d;n;/^\S/ba;/^\s*Vendor:/bc
s/.*PCI address: //p;tb;bd' file
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With