8
2
Title kind of says it all: I would like to get those neat colored columns of the output of something like ls -al
, say, as in 10basetom’s answer to this question.
8
2
Title kind of says it all: I would like to get those neat colored columns of the output of something like ls -al
, say, as in 10basetom’s answer to this question.
8
This is doable with awk
. Unfortunately, since the format of ls -l
is unspecified, it is not possible to come up with a solution that will work on every system so some adjustment of which colour to use for which column will be necessary on some systems.
First off, we want to preserve the original spaces used by ls -l
. Otherwise, the column alignment will be incorrect. We can do this with the FPAT
option, thanks to this SO answer:
ls -la | awk '
BEGIN {
FPAT = "([[:space:]]*[^[:space:]]+)";
OFS = "";
}
In awk
, each positional param ($1
, $2
, etc.) refers to one field, i.e. one column on the current row. What the FPAT
option above did is redefine each field to include all preceding spaces, so when you print
it back out it keeps the spaces so the columns stay in the same position.
Now we can simply edit each field to insert the colour code, and then print the edited output:
{
$2 = "\033[31m" $2 "\033[0m";
$3 = "\033[36m" $3 "\033[0m";
$4 = "\033[36m" $4 "\033[0m";
$5 = "\033[31m" $5 "\033[0m";
$6 = "\033[36m" $6 "\033[0m";
$7 = "\033[36m" $7 "\033[0m";
$8 = "\033[31m" $8 "\033[0m";
print
}
'
Notice that each column is reset back to default (the 0
between the [
and m
) afterwards. If you want the colour to run across multiple columns, you can omit that code. Personally, I prefer to specify each column independently.
You can define the a reusable command in your .bashrc
. For example:
lsc() {
ls -la | awk '
BEGIN {
FPAT = "([[:space:]]*[^[:space:]]+)";
OFS = "";
}
{
$2 = "\033[31m" $2 "\033[0m";
$3 = "\033[36m" $3 "\033[0m";
$4 = "\033[36m" $4 "\033[0m";
$5 = "\033[31m" $5 "\033[0m";
$6 = "\033[36m" $6 "\033[0m";
$7 = "\033[36m" $7 "\033[0m";
$8 = "\033[31m" $8 "\033[0m";
print
}
'
}
You may need to restart your bash
session (or run source ~/.bashrc
) for this function definition to run.
From here, you can just call lsc
, which should give you the output you desire:
Awesome guys, this is almost what I want ;-) Seriously, though, I'd like to add one more twist and have the file names colored. ls -al --color=auto would do that, but if I just add the --color option to the solutions above, the color codes seem to get stripped. Can we get awk to keep those? – Pirx – 2018-02-14T02:24:47.120
Second comment, this is more out of curiosity: In the answer I referenced in my original question, it looks like 10basetom did not use any of the above, and still had the colored columns. I wonder if that's because he used a different version of ls, or some fancy smart terminal? – Pirx – 2018-02-14T02:32:46.250
@Pirx The colouring in the answer is applied by the Stack Exchange software. It's not coming from their terminal. It's just because the output was pasted in a code block and the question had a [tag:bash] tag, which automatically tries to apply Bash syntax highlighting to any code tags in the question and answers ... which is actually incorrect in this case. Same reason the strings in the code are red in my answer, even though I didn't intentionally colour them. – Bob – 2018-02-14T02:41:56.030
1@Pirx Use --color=always
. As long as you don't apply different colours to the filename column ($9
in my example), awk
should pass them through. – Bob – 2018-02-14T02:42:41.073
@Pirx Side note, --color=always
is a GNU extension so if you're on a non-GNU system (e.g. macOS, other BSDs) you'll need to either install the GNU version or use an alternative.
Hah, thanks, that does the trick. I have installed the GNU coreutils (and a couple of others, including the latest version of bash) on my Mac, so I'm good on that front. – Pirx – 2018-02-14T03:21:57.647
6
This will print the second column of ls -alF
in red, the third through eighth in blue and the ninth in black:
ls -alF | awk -v black=$(tput setaf 0) -v red=$(tput setaf 1) -v blue=$(tput setaf 4) '{$2=red $2; $3= blue $3; $9=black $9} 1'
This is just intended as an example. You may customize this to your heart's content.
For those who prefer their code spread out over multiple lines:
ls -alF | awk -v black=$(tput setaf 0) \
-v red=$(tput setaf 1) \
-v blue=$(tput setaf 4) \
'{
$2=red $2
$3= blue $3
$9=black $9
}
1'
tput
is a utility to generate a wide variety of control codes for your terminal. For example, tput setaf n
sets the foreground color to n
where n
can range from 0 to 7
0 – Black
1 – Red
2 – Green
3 – Yellow
4 – Blue
5 – Magenta
6 – Cyan
7 – White
You can read more about tput
and its color capabilities here.
The awk code defines variables black
, red
, and blue
that contain the terminal codes for black, red, and blue, respectively. These codes are placed at the beginning of whatever column we want to color.
One trick is that color codes don't reset on their own. So, whatever the last color you specify on one line will, unless another color command is specified, be the default color for the next line.
1Huh, good call on defining variables. Didn't know you could do that from within awk
! I'd suggest you include the pattern to preserve column alignment too :) – Bob – 2018-02-14T00:27:50.047
@Bob And, I like your FPAT
trick for keeping the spacing correct. – John1024 – 2018-02-14T00:37:26.350
Well, this is a neat idea! But what OS are you on? – JakeGould – 2018-02-13T23:42:03.477
2That looks to be (incorrectly) Bash syntax-highlighted by the SE software. Looks like it's not coloured by column but rather digits (numbers) get one colour and anything starting with an uppercase get another. Colouring per-column is doable but rather different. – Bob – 2018-02-13T23:44:26.880
3
In the general sense, you can split the output on the column separators with
– Bob – 2018-02-13T23:46:04.943sed
orawk
and insert an ANSI escape sequence.Related: https://superuser.com/q/665274
– Tyson – 2018-02-13T23:53:39.777I'm on the Windows 10 Ubuntu subsystem, but transitioning to macOS (given the complete disaster that WinX turned out to be...) – Pirx – 2018-02-14T02:21:04.393