Search code examples
awksedgrepprintf

Using awk to get PCI Address


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.


Solution

  • 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.