Other x-fetch , gawk pipe

Next script demostrates the use of gawk, which can ignore case as opposed to awk.
First install gawk,ufetch,neofetch,fastfetch,cpufetch,nvidia-drivers,dmidecode
Use self explaining script below (note i used ai).

Code:
root@myfreebsd:/SSD/home/x/KEEP/FILES/Scripts # cat system_info_a
#!/bin/sh

# Define the function to print dashes
myminus() {
    # Runs gawk to print a specific number of dashes
    gawk 'BEGIN { while(i++<85) printf "-"; print "" }'
}

# Define the shared gawk functions ONCE - Includes fmt and your new my_printf function
GAWK_FUNC='
# General layout function to print formatted and aligned output fields
function my_printf(p1, p2) {
    printf "%-18s : %s\n", p1, p2
}

# Shared function to split string text, trim whitespace, and call my_printf
function fmt(str, arr) {
    # Isolate the field label from the trailing information using the colon delimiter
    split(str, arr, ":")
    # Delete leading spaces from the extracted label name in the first array slot
    gsub(/^[ \t]*/, "", arr[1])
    # Delete everything up to the first colon character from the full text string
    gsub(/^[^:]*:/, "", str)
    # Delete any remaining leading empty spaces from the text value string
    gsub(/^[ \t]*/, "", str)
    my_printf(arr[1], str)
}
'

myminus

# 1. pfetch
PF_INFO="os kernel" pfetch | gawk "$GAWK_FUNC"'
BEGIN { IGNORECASE=1 }
{
    # Delete all ANSI color escape codes from the current line
    gsub(/\x1b\[[0-9;]*m/, "")
    # Delete all hidden, non-printable characters from the current line
    gsub(/[^[:print:]]/, "")
}
# Only process the line if it contains the word "os"
/os/ {
    # Delete the word "os" and any spacing from the very start of the text
    gsub(/^.*os[ \t]*/, "", $0)
    # Call your new general my_printf function
    my_printf("Os", $0)
}
# Only process the line if it contains "kernel" but does NOT contain "host"
/kernel/ && !/host/ {
    # Delete the word "kernel" and any spacing from the very start of the text
    gsub(/^.*kernel[ \t]*/, "", $0)
    # Call your new general my_printf function
    my_printf("Kernel", $0)
}'

# 2. ufetch
ufetch | gawk "$GAWK_FUNC"'
BEGIN { IGNORECASE=1 }
{
    # Delete all colors and special VT100 graphics drawing characters
    gsub(/\x1b\[[0-9;]*m|\x1b\(B/, "")
    # Delete all remaining non-printable hidden characters from the line
    gsub(/[^[:print:]]/, "")
}
# Only process the line if it contains the word "kernel"
/kernel/ {
    # Find the character position where the text "KERNEL:" begins
    match($0, /KERNEL:.*/);
    # Extract everything from that found position to the end of the line
    line = substr($0, RSTART);
    # Separate the extracted ufetch kernel data using the colon delimiter
    split(line, a, ":");
    # Delete any spaces at the beginning of the text inside the second array slot
    gsub(/^[ \t]*/, "", a[2]);
    # Call your new general my_printf function
    my_printf("KERNEL", a[2])
}'

myminus

# 3. neofetch
neofetch \
--off \
--title_fqdn on --package_managers on --os_arch on --speed_shorthand on \
--cpu_brand on --cpu_speed on --distro_shorthand on --kernel_shorthand on \
--uptime_shorthand on --gpu_brand on --de_version on --gtk_shorthand on \
--gtk2 on --gtk3 on --shell_path on --shell_version on --disk_percent on \
--memory_percent on --color_blocks off --bar_border on | \
gawk "$GAWK_FUNC"'
# Skip lines that contain Resolution, Kernel, Theme, Icons, FreeBSD, or multiple dashes
!/Resolution|Kernel|Theme|Icons|FreeBSD|\-\-\-\-/ {
    # Delete colors and raw non-printable control characters from the line
    gsub(/\x1b\[[0-9;]*m|[^[:print:]]/, "")
    # Check if the text line contains a colon divider before executing fmt (which performs internal gsubs)
    if ($0 ~ /:/) {
        # Call the short formatting function which internalizes my_printf
        fmt($0)
    }
}'

myminus

# 4. fastfetch
fastfetch --detect-version --logo none | gawk "$GAWK_FUNC"'
BEGIN { IGNORECASE=1 }
NR > 25 { exit }
# Skip lines that match any of these system or hardware labels
# !/^WM[ \t]*:/ tells gawk: 
# "Do not process the line if it starts (^) 
# with WM followed by spaces and a colon."
!/kernel|packages|shell|terminal|memory|uptime|cpu|lxqt|freebsd|\-\-\-\-/ && !/^WM[ \t]*:/ {
# Check if the text line contains a colon divider before executing fmt (which performs internal gsubs)
    if ($0 ~ /:/) {
        # Call the short formatting function which internalizes my_printf
        fmt($0)
    }
}'

myminus

# 5. cpufetch
cpufetch --logo-long -F | gawk "$GAWK_FUNC"'
# Skip any lines that contain the word "size" or "SIZE"
!/size/ && !/SIZE/ {
    # Delete color strings and unprintable characters from the current line
    gsub(/\x1b\[[0-9;]*m|[^[:print:]]/, "")
    # Extract only the hardware info text by cutting off the first 57 logo characters
    line = substr($0, 58)
    # Check if the extracted text line has content before passing it to fmt (which performs internal gsubs)
    if (line ~ /[^[:space:]]/) {
        # Call the short formatting function which internalizes my_printf
        fmt(line)
    }
}'

myminus

# 6. nvidia-smi metrics
nvidia-smi --query-gpu=name,driver_version,fan.speed,temperature.gpu,pstate,power.draw,power.limit,memory.used,memory.total,utilization.gpu --format=csv,noheader,nounits 2>/dev/null | \
 gawk "$GAWK_FUNC"'
BEGIN {
    # Define display names for each metric position index
    labels[1] = "NVIDIA GPU"
    labels[2] = "Driver Version"
    labels[3] = "NVIDIA Fan"
    labels[4] = "NVIDIA Temp"
    labels[5] = "Perf State"
    labels[6] = "NVIDIA Power"
    labels[7] = "NVIDIA VRAM"
    labels[8] = "GPU Util"
}
{
    # Verify the line does not contain driver errors or blank metrics before processing
    if ($0 ~ /invalid field/ || $0 ~ /Not Supported/ || $0 == "") next;

    # Parse out individual csv elements using a comma and space sequence as the field separator
    split($0, val, ", ")
   
    # Construct combined data fields for power and memory indexes
    pwr = (val[6] != "" && val[7] != "") ? val[6] "W / " val[7] "W" : ""
    vram = (val[8] != "" && val[9] != "") ? val[8] "MiB / " val[9] "MiB" : ""

    # Map raw value data and custom text combinations into a clean loop array
    data[1] = val[1]
    data[2] = val[2]
    data[3] = (val[3] != "") ? val[3] "%" : ""
    data[4] = (val[4] != "") ? val[4] "°C" : ""
    data[5] = val[5]
    data[6] = pwr
    data[7] = vram
    data[8] = (val[10] != "") ? val[10] "%" : ""

    # Loop sequentially from 1 to 8 across all populated monitoring properties
    for (i = 1; i <= 8; i++) {
        # Verify the target index contains text data before passing it to the aligned layout function
        if (data[i] != "") {
            my_printf(labels[i], data[i])
        }
    }
}'

# 7. Extract both Graphics (G) and Compute (C) processes from the native output layout
nvidia-smi 2>/dev/null | \
 gawk "$GAWK_FUNC"'
BEGIN { in_proc = 0 }
/Processes:/ { in_proc = 1; next }
in_proc && /^\|[[:space:]]+[0-9]+/ {
    # Strip out the exterior layout boundary pipe characters before extracting process text
    gsub(/^\||\|$/, "", $0)
   
    pid = $4
    type = $5
    mem = $NF
   
    pname = ""
    # Loop across the middle fields to reassemble the process name even if it contains space characters
    for(i=6; i<NF; i++) {
        pname = (pname == "" ? $i : pname " " $i)
    }
   
    # Verify that the system PID index was collected successfully before sending to standard display
    if (pid != "") {
        my_printf("Process " pid, pname " (" mem ")")
    }
}'

myminus

# 8. SYSTEM HARDWARE HARD-QUERY (Dmidecode Component Mapper)
# Extracts low-level hardware and firmware data from the system's 
# Desktop Management Interface (DMI) table using specific SMBIOS structure types.
# Targeted DMI Structure Types:
#   - Type 0  : BIOS Information (Vendor, version, release date, runtime size)
#   - Type 1  : System Information (Manufacturer, product name, serial number, UUID)
#   - Type 2  : Baseboard Information (Motherboard manufacturer, model, asset tags)
#   - Type 4  : Processor Information (Socket type, CPU family, max speed, cores)
#   - Type 16 : Physical Memory Array (Maximum capacity, error correction types)
#   - Type 17 : Memory Device (Individual RAM slots, speeds, form factors, serials)
#   - Type 32 : System Boot Information (Status and structural integrity checks)
dmidecode --type=0,1,2,4,16,17,32 2>/dev/null | gawk '
# Skip header metadata files and empty gap lines completely
/^#/ || /^$/ || /SMBIOS/ || /Handle 0x/ || /Found SMBIOS/ { next }

# Capture primary section headers (lines with zero leading tabs)
/^[A-Za-z]/ {
    # sub: Strip trailing trailing spaces, tabs, carriage returns, or newlines from the header name
    sub(/[ \t\r\n]*$/, "", $0)
    sect = $0
    next
}

# Process rows indented with literal tabs
/^\t/ {
    # match: Find the continuous block of leading tab characters at the absolute start of the line to evaluate depth
    match($0, /^\t+/)
    tab_depth = RLENGTH

    clean_line = $0
    # sub: Clear out all leading spaces and tabs from the copy of the line text
    sub(/^[ \t]*/, "", clean_line)
    # sub: Strip trailing spaces, tabs, carriage returns, or newlines from the line text
    sub(/[ \t\r\n]*$/, "", clean_line)

    # if: Check if the line is exactly one tab level deep (Primary attribute level)
    if (tab_depth == 1) {
        # if: Check if the text entry ends with a colon, signaling a sub-category heading (like Characteristics:)
        if (clean_line ~ /:$/) {
            # sub: Remove the trailing colon character from the end of the sub-category string name
            sub(/:$/, "", clean_line)
            sub_cat = clean_line
            print sect " | " sub_cat ":"
        } else {
            sub_cat = ""
            print sect " | " clean_line
        }
    } 
    # else if: Check if the line is exactly two tabs level deep (Nested sub-property listing items)
    else if (tab_depth == 2) {
        # if: Check if an active sub-category heading was registered from the previous rows
        if (sub_cat != "") {
            print sect " | " sub_cat ": | " clean_line
        } else {
            print sect " | " clean_line
        }
    }
}'


[/CODE]
 
Last edited:
A sample output is,

Code:
-------------------------------------------------------------------------------------
Os                 : FreeBSD 15.1-RELEASE-p3
Kernel             : 15.1-RELEASE-p3
KERNEL             : GENERIC 1501000
-------------------------------------------------------------------------------------
Uptime             : 3 days, 1 hour, 50 mins 
Packages           : 2513 (pkg) 
Shell              : /bin/sh 
DE                 : LXQt 2.4.0 
WM                 : Metacity (Marco) 
Terminal           : xfce4-terminal 
Terminal Font      : Monospace 12 
CPU                : 12th Gen Intel i5-12400 (12) @ 2.4GHz 
GPU                : TU106 [GeForce RTX 2060 12GB] 
Memory             : 8231MiB / 32491MiB (25%) 
-------------------------------------------------------------------------------------
Host               : MAG H610 Codex 5 (MS-B930) (1.2)
Display (HP w2207) : 1920x1080 in 22", 60 Hz [External] *
Display (HP 527sh) : 1920x1080 in 27", 60 Hz [External]
WM Theme           : BlueMenta
Theme              : qt6ct-style [Qt], Breeze [GTK2], Mojave-Light-blue [GTK3], Sweet-Dark [GTK4]
Icons              : menta [Qt], menta [GTK3], breeze [GTK4]
Font               : Sans (11pt) [Qt], Sans (11pt) [GTK3], Fira Sans (10pt) [GTK4]
Cursor             : Bibata-Modern-Amber (23px)
GPU 1              : Intel UHD Graphics 730 [Integrated]
GPU 2              : NVIDIA GeForce RTX 2060 12GB [Discrete]
Swap               : 11.20 GiB / 64.00 GiB (18%)
Disk (/)           : 127.36 GiB / 213.08 GiB (60%) - ufs
Disk (/SSD)        : 112.00 KiB / 306.61 GiB (0%) - zfs
-------------------------------------------------------------------------------------
Name               : 12th Gen Intel(R) Core(TM) i5-12400
Microarchitecture  : Alder Lake
Technology         : 10nm
Max Frequency      : 4.400 GHz
Cores              : 6 cores (12 threads)
AVX                : AVX,AVX2
FMA                : FMA3
L1i Size           : 32KB (192KB Total)
L1d Size           : 48KB (288KB Total)
L2 Size            : 1.25MB (7.5MB Total)
L3 Size            : 18MB
Peak Performance   : 844.80 GFLOP/s
-------------------------------------------------------------------------------------
NVIDIA GPU         : NVIDIA GeForce RTX 2060
Driver Version     : 595.84
NVIDIA Fan         : 41%
NVIDIA Temp        : 33°C
Perf State         : P8
NVIDIA Power       : 14.40W / 184.00W
NVIDIA VRAM        : 10952MiB / 12288MiB
GPU Util           : 13%
Process 5980       : firefox (150MiB)
Process 33990      : /usr/local/libexec/Xorg (281MiB)
Process 64882      : llama-server (10513MiB)
-------------------------------------------------------------------------------------
Platform Firmware Information | Vendor: American Megatrends International, LLC.
Platform Firmware Information | Version: E.40
Platform Firmware Information | Release Date: 09/03/2024
Platform Firmware Information | Address: 0xF0000
Platform Firmware Information | Runtime Size: 64 KiB
Platform Firmware Information | ROM Size: 32 MiB
Platform Firmware Information | Characteristics:
Platform Firmware Information | Characteristics: | PCI is supported
Platform Firmware Information | Characteristics: | Firmware is upgradeable
Platform Firmware Information | Characteristics: | Firmware shadowing is allowed
...
 
Last edited:
You could modify it so that if nvidia-drivers are not installed (on for example Intel only or AMD only systems) - pointless --- line is not displayed 2nd time.

Other thing.

Code:
./test.sh: pfetch: not found
./test.sh: ufetch: not found

Instead of showing error each time - it would be good to check for all needed/suggested software at the start and display one nice message such as:

Code:
Install 'sysutils/pfetch' package to display disks temperatures.

IMHO it would also be good to just get all the info you want to display and display it once - not like Openbox from one tool, then Openbox from 2nd tool again, etc.

Regards,
vermaden
 
Back
Top