While the other answers do work, performing a separate install call per package has a few issues:
- It removes a lot of the points/strength of
apt and its ability to determine which packages would share dependencies or clash ahead of time
- If sudo is required (usually), then the sudo timeout can be reached before all packages are installed
Recently I came across this issue as I was moving a personal machine over from one Ubuntu 18.04 (Bionic) install to another newer clean version of Ubuntu 20.04 (Focal), but wanted to install the same packages on the new machine... and I came up with a nice solution:
I started with a file containing a list generated from the old machine, which had each package name on its own separate line, easily generated by the following:
apt list --installed 2>/dev/null | sed 's/\/.*//g > packages'
I then ran the file list through apt to filter the list down to all packages that were available on the newer machine/repo and that weren't virtual, while piping the results to another file, echoing the progress, and the ultimately installing the resulting packages:
# Filter packages for those available
while read package; do apt show "$package" 2>/dev/null | grep -qvz 'State:.*(virtual)' && echo "$package" >>packages-valid && echo -ne "\r\033[K$package"; done <packages
# Install the available packages all at once
sudo apt install $(tr '\n' ' ' <packages-valid)
And that worked!
Hopefully this finds someone else well. :)