9

I want to show only specific columns for all the records in the command.

Example: docker ps shows me data in 10 columns. It can have space in between the column headers. My requirement is to get only 2-4 columns in some sequence.

Is there a direct way to do that in any of the commands that respond in a tabular way?

I am new to Linux and thinking if this can be feasible. Thanks.


For example:

$ docker ps
CONTAINER ID  IMAGE   COMMAND     CREATED             NAMES
123           image   "ABC DEF"   10 hours ago        image ABC

Here in the above scenario, CONTAINER ID is one header column but there is space, and in the row for NAMES columns can have space in between.

Using AWK, CUT etc it is trickier to write a common script for all the commands because they work on "space" logic.

jww
  • 97,681
  • 90
  • 411
  • 885
stackjohnny
  • 645
  • 3
  • 7
  • 22
  • 3
    read `man docker-ps` -- there's a handy `--format` option that does just what you want. – glenn jackman Dec 22 '18 at 20:01
  • 3
    Possible duplicate of [How to specify more spaces for the delimiter using cut?](https://stackoverflow.com/q/7142735/608639), [Using cut command to remove multiple columns](https://stackoverflow.com/q/13690461/608639), etc. – jww Dec 22 '18 at 21:20
  • its not related to docker ps only, but i need some common script for all the commands – stackjohnny Dec 24 '18 at 07:59

3 Answers3

10

You can use awk like that:

$ ps | awk '{print $2 " " $3 " " $4}'
TTY TIME CMD
pts/22 00:00:00 bash
pts/22 00:00:00 ps
pts/22 00:00:00 awk

Or together with column -t for more readable output:

$ ps | awk '{print $2 " " $3 " " $4}' | column -t
TTY     TIME      CMD
pts/22  00:00:00  bash
pts/22  00:00:00  ps
pts/22  00:00:00  awk
pts/22  00:00:00  column

As William Pursell noted in the comment below awk command can be simplified:

$ ps | awk '{print $2, $3, $4}' | column -t
TTY    TIME      CMD
pts/9  00:00:00  bash
pts/9  00:00:00  ps
pts/9  00:00:00  awk
pts/9  00:00:00  column
Arkadiusz Drabczyk
  • 11,227
  • 2
  • 25
  • 38
  • 1
    this will work, but it will fail when the column heading or the data have spaces in that. `command` SR NO DETAIL DATE here awk print 1 will be SR, print 2 will be NO – stackjohnny Dec 22 '18 at 14:58
  • This is how `awk` works, it separates columns by a whitespace. To do what you want you have to use some `ps` options to tell it to display only some columns. Post entire output of `docker ps` and `ps --version`. – Arkadiusz Drabczyk Dec 22 '18 at 15:03
  • yes, awk works that way, so is there any other way? `ps` option in this case is the command to docker, so passing column name will not work. – stackjohnny Dec 22 '18 at 15:08
  • Probably cleaner to write `print $2, $3, $4` – William Pursell Dec 22 '18 at 16:58
  • Thanks, I updated my answer. – Arkadiusz Drabczyk Dec 22 '18 at 17:02
  • For this particular `docker ps` example it is possible to use more than one space as a separator in awk: `docker ps | awk -F ' {2,}' '{print $2 " " $3 " " $4}'` – andrey Dec 23 '18 at 11:11
8

Piping the output to tr and cut:

docker ps | tr -s " " | cut -d " " -f 2-4

-s flag on tr squeezes characters and leaves only one " "

-d on cut tells to split field by " ".

Gonzalo Matheu
  • 8,984
  • 5
  • 35
  • 58
  • 7
    Docker actually has a filter docker ps --format "table {{.ID}}\t{{.Names}}" Replace ID or Names with whatever columns you want – Phillip Kigenyi Apr 01 '20 at 09:05
1

Sample output using Perl. Perl has 0 based index, so you have to use 1..3 meaning from 2 to 4

$ ps
      PID    PPID    PGID     WINPID   TTY         UID    STIME COMMAND
    14556   11424   14556       6944  cons0     197609 22:10:27 /usr/bin/ps
    11424       1   11424      11424  cons0     197609 22:41:21 /usr/bin/bash
$ ps | perl -F'\s+' -lane ' print "@F[1..3]" '
PID PPID PGID
11208 11424 11208
11424 1 11424
380 11424 11208

If you don't need headers.. then

$ ps | perl -F'\s+' -lane 'if($.>1) { print "@F[1..3]" } '
6072 11424 6072
11424 1 11424
stack0114106
  • 8,534
  • 3
  • 13
  • 38