Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

I have several plain text tables (table.txt), with time series going from 2005 until 2099. Unfortunately some of them are missing the last day of the time series 31.12.2099, as follow:

YEAR MONTH DAY RES
2005 1     1   1000
2005 1     2   1001
[...]
2099 12    29  1002
2099 12    30  1003

How can I add the missing day of the time series (31.12.2099) by pasting the value (RES) of the previous day? Considering the minimal example provided, the output should look like that:

YEAR MONTH DAY RES
2005 1     1   1000
2005 1     2   1001
[...]
2099 12    29  1002
2099 12    30  1003
2099 12    31  1003
share|improve this question
    
This is a task with many sub-tasks. Which of these sub-tasks is causing you problems? – Stig Hemmer yesterday
    
Are you permitted to use awk or perl? – Mark Plotnick yesterday
    
@StigHemmer - The first problematic task is to find which table missed the 31.12.2099. Afterward I think I am able to paste the value of the previous day. – steve yesterday
    
@MarkPlotnick - Definitely permitted to use them! – steve yesterday
    
How are the columns delimited? A single tab? Multiple spaces? – Mark Plotnick yesterday

3 Answers 3

up vote 3 down vote accepted

With awk:

awk '{a=$0}1; END{$0=a; if($1==2099&&$2==12&&$3==30){$3=31;print}}' file | column -t
  • r=$0 set the a variable to the whole line.
  • 1 a true condition that all line are printed
  • END{...} that block is executed when all lines are processed
    • $1==2099&&$2==12&&$3==30 if the last line was december 30th, 2099 (the 13th is missing)
    • $3=31 set the day to 31
    • print and print that additional line.
  • column -t is to columnate the list.

The result with your input file:

YEAR  MONTH  DAY  RES
2005  1      1    1000
2005  1      2    1001
...
2099  12     29   1002
2099  12     30   1003
2099  12     31   1003
share|improve this answer

The script adds to all table files which have 30 in the last line followed by 2 space and 4 symbols RES the new line with 2099 12 31 RES(from line before):

sed -i '$ s/30\(  ....\)$/&\n2099 12    31\1/' table*
share|improve this answer

Assuming your file names all start with table (if they don't, just change the glob pattern to something that matches all of them), you can do:

for file in table*; do
    awk -vi="2099 12    31" '1;END{if($0!=i){print i,$NF}}' "$file" > "$file".new
done

The awk command defines the variable i to be the missing line. The 1; just prints every line and the END{} block is executed once the entire file has been read. When inside the END{} block, $0 will be the last line read, the last line of the file. If that is not equal to the value of i, print i and the last field (NF) of the last line of the file.

share|improve this answer
    
@Costas d'oh! Of course, very good point. Thanks and fixed. – terdon yesterday

Your Answer

 
discard

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.