skip to Main Content

Question:

Is it possible to exclude some of a commands output its output based on an array of words?**

Why?

On Ubuntu/Debian there are two ways to list all available pkgs:

  1. apt list (show all available pkgs, installed pkgs too)
  2. apt-cache search . (show all available pkgs, installed pkgs too)

Difference is, the first command, you can exclude all installed pkgs using grep -v, problem is unlike the first, the second command you cannot exclude these as the word "installed" isnt present. Problem with the first command is it doesnt show the pkg description, so I want to use apt-cache search . but excluding all installed pkgs.

# List all of my installed pkgs,
# Get just the pkg's name,
# Swap newlines for spaces,
# Save this list as an array for exclusion.

INSTALLED=("$(apt list --installed 2> /dev/null | awk -F/ '{print $1}' | tr 'rn' ' ')")

I then tried:

apt-cache search . | grep -v "${INSTALLED[@]}"

Unfortunately this doesnt work as I still see my installed pkgs too so I’m guessing its excluding the first pkg in the array and not the rest.

Again thank you in advance!

2

Answers


  1. Sorry if I’m misunderstanding, but you just want to get the list of packages which are not installed, right?

    If so, you can just do this –

    apt list --installed=false | grep -v '[installed'
    
    Login or Signup to reply.
  2. Would you please try the following:

    #!/bin/bash
    
    declare -A installed                            # an associative array to memorize the "installed" command names
    
    while IFS=/ read -r cmd others; do              # split the line on "/" and assign the variable "cmd" to the 1st field
        (( installed[$cmd]++ ))                     # increment the array value associated with the "$cmd"
    done < <(apt list --installed 2> /dev/null)     # excecute the `apt` command and feed the output to the `while` loop
    
    while IFS= read -r line; do                     # read the whole line "as is" because it includes a package description
        read -r cmd others <<< "$line"              # split the line on the whitespace and assign the variable "cmd" to the 1st field
        [[ -z ${installed[$cmd]} ]] && echo "$line" # if the array value is not defined, the cmd is not installed, then print the line
    done < <(apt-cache search .)                    # excecute the `apt-cache` command to feed the output to the `while` loop
    
    • The associative array installed is used to check if the command is
      installed.
    • The 1st while loop scans over the installed list of the command and
      store the command names in the associative array installed.
    • The 2nd while loop scans over the available command list and if the
      command is not found in the associative array, then print it.

    BTW your trial code starts with #!/bin/sh which is run with sh, not bash.
    Please make sure it looks like #!/bin/bash.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search