Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Let's say I have a file that contains these lines:

02.03.14    14.50   14.50   0.00    Desc
02.03.14    17.00   0.00    17.00   Desc
01.03.14    2.82    1.68    calc    Desc
02.03.14    1.04    0.00    1.04    Desc
06.03.14    6.00    0.00    6.00    Desc
08.03.14    11.76   2.98    calc    Desc
10.03.14    3.27    0.00    3.27    Desc

I want to replace all column entries containing calc (only appearing in the 4th column) to contain the difference between the 3nd and 2nd column, so 4th=3rd-2nd.

How can I do so?

share|improve this question
@1_CR Now it's possible to use any tool you know :)! – polym Jul 27 '14 at 21:20
up vote 6 down vote accepted

Sed can't do arithmetic¹. Use awk instead.

awk '
    $4 == "calc" {sub(/calc(  |\t)/, sprintf("%-6.2f", $3 - $2))}

The 1 at the end means to print everything (after any preceding transformation). Instead of the text substitution with sub, you could assign to $4, but doing so replaces inter-column space (which can be any sequence of spaces and tabs) by a single space character. If your columns are tab-separated, you can use

awk '
    BEGIN {ORS = "\t"}
    $4 == "calc" {$4 = sprintf("%.2f", $3 - $2))}

¹ Yes, yes, technically it can since it's Turing-complete. But not in any sane way.

share|improve this answer
Thanks @Gilles. I made some changes, though, because I have tabs instead of whitespaces as delimiters for each row, so I added a tab after calc and after the sprintf. – polym Jul 27 '14 at 23:11
awk -F "\t" '$4 == "calc" {$4 = $3-$2}1' OFS='\t' file
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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