I have a text file with lots of package names.


# comment
# installing package3 because it was needed for...
package 3

package 4

How can I mass install all packages inside the text file without removing the comments?


Something along these lines ought to do the trick.

apt-get install $(grep -vE "^\s*#" filename  | tr "\n" " ")

The $(something) construction runs the something command, inserting its output in the command line.

The grep command will exclude any line beginning with a #, optionally allowing for whitespace before it. Then the tr command replaces newlines with spaces.

  • 5
    tr will fail with multi-byte end-of-line sequences (think \r\n), why don't you use xargs? – Ivan Anishchuk Feb 17 '16 at 16:20
  • You can also ignore trailing comments apt-get install $(grep -vE "^\s*#" Aptfile | sed -e 's/#.*//' | tr "\n" " ") – Jamie Cook Sep 16 '20 at 23:46

The following command is a (slight) improvement over the alternative because sudo apt-get install is not executed when the package list is empty.

xargs -a <(awk '! /^ *(#|$)/' "$packagelist") -r -- sudo apt-get install

Note that the -a option reads items directly from a file instead of standard input. We don't want to pipe a file into xargs because stdin must remain unchanged for use by apt-get.

  • xargs is the right way to do this. Trick with <() is neat. – Ivan Anishchuk Feb 17 '16 at 16:19
  • 1
    That's indeed the better solution because xargs makes sure ARG_MAX is not reached. – phk Jun 12 '16 at 11:45
  • It has to be xargs -a $(awk '/^\s*[^#]/' "$packagelist") -r -- sudo apt-get -y install, not "<(" but "$(" and the option -y for apt-get would be a good idea. – user567188 Jul 11 '16 at 20:19
  • Process substitution redirects the output of awk into a file descriptor for xargs -a to read from. So you definitely want <( and not $(. Just try it and you'll see what I mean. If the command is to be running unattended and you already know exactly what's going to be installed then sure, they -y flag is a good idea. – Six Jul 12 '16 at 3:01

Given a package list file package.list, try:

sudo apt-get install $(awk '{print $1'} package.list)
  • How does it help with #? – greatvovan Dec 18 '20 at 2:40

I use this simple solution:

grep -vE '^#' file.txt | xargs sudo apt install -y

grep finds all lines that don't start with a # and gives them as arguments to sudo apt install.


Well, here's my solution to install a list of packages I have for fresh install:

sudo apt install -y $(grep -o ^[^#][[:alnum:]-]* "filename")

In a bash function :

aptif () {
    sudo apt install -y $(grep -o ^[^#][[:alnum:]-]* "$1")

grep explanation :

  • -o keep only the part of line that matches the expression
  • ^[^#] anything that does not start with a #
  • [[:alnum]-]* a sequence of letters, numbers and -

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.