Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using awk to get PCI Address

Tags:

grep

printf

sed

awk

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.

like image 521
dasunsrule32 Avatar asked Nov 01 '25 02:11

dasunsrule32


2 Answers

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.

like image 85
Ed Morton Avatar answered Nov 03 '25 02:11

Ed Morton


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 
like image 23
potong Avatar answered Nov 03 '25 03:11

potong



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!