最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

AWK add line number to date - Stack Overflow

programmeradmin2浏览0评论

I have an input file.

A
B
C

I use a command that gives the result.

awk -v date="$(date +%d-%m-%Y --date="$NR day")" '{print $0, date}' File_1

A 16-02-2025
B 16-02-2025
C 16-02-2025

I want to get the result.

A 16-02-2025
B 17-02-2025
C 18-02-2025

I have an input file.

A
B
C

I use a command that gives the result.

awk -v date="$(date +%d-%m-%Y --date="$NR day")" '{print $0, date}' File_1

A 16-02-2025
B 16-02-2025
C 16-02-2025

I want to get the result.

A 16-02-2025
B 17-02-2025
C 18-02-2025
Share Improve this question asked Feb 15 at 14:30 Tedee12345Tedee12345 1,3624 gold badges17 silver badges26 bronze badges 1
  • What should the output be for line 32 of the input - 32-02-2025 (i.e. a date that doesn't exist) or something else? – Ed Morton Commented Feb 16 at 14:56
Add a comment  | 

5 Answers 5

Reset to default 5

What I would do:

$ awk '{printf "%s ", $0; system("date +%d-%m-%Y -d "NR"\\ day")}' File_1
A 16-02-2025
B 17-02-2025
C 18-02-2025

When you do:

-v date="$(date +%d-%m-%Y --date="$NR day")"

the variable is assigned only one time.

variation of @Gilles's answer using getline

awk '{ "date +%d-%m-%Y --date=\""NR" day\""|getline theDate; print $0, theDate }' File_1 
A 16-02-2025
B 17-02-2025
C 18-02-2025

If your flavor of awk (eg, GNU awk, mawk) has support for the mktime() / strftime() functions you can perform the date math (+1 day) inside awk and eliminate the overhead of repeated OS/system date calls:

awk -v date_in="$(date '+%d-%m-%Y' --date="$NR day")" '

function fmt_date() { return strftime("%d-%m-%Y", epoch) }       # convert epoch (seconds) to desired format

BEGIN { split(date_in,dt,"-")
        epoch = mktime(dt[3] " " dt[2] " " dt[1] " 12 00 00")    # generate initial epoch (seconds); use 12:00:00 (noon)
                                                                 # to eliminate any issues around daylight savings
      }

      { print $0, fmt_date()
        epoch += 86400                                           # +1 day
      }

' File_1

NOTES:

  • we could also pull $(date '+%d-%m-%Y' --date="$NR day") into the awk script, OP would only need to provide NR as an input parameter; the systime() function would then come in handy as a means of allowing the awk script to obtain the 'current time'; if OP opts to try this and has problems getting it to work then I'd suggest asking a new question
  • see GNU awk - Time Functions for details on the mktime() / strftime() / systime() functions

Taking for a test drive (today = 15 Feb 2025):

######## NR=-3

A 12-02-2025
B 13-02-2025
C 14-02-2025

######## NR=0

A 15-02-2025
B 16-02-2025
C 17-02-2025

######## NR=1

A 16-02-2025
B 17-02-2025
C 18-02-2025

######## NR=4

A 19-02-2025
B 20-02-2025
C 21-02-2025
awk -v date="$(date +%d-%m-%Y --date="$NR day")" '{print $0, date}' File_1

You could not use built-in GNU AWK variable inside value for value setting by -v option. It does attempts to pull NR shell variable, founds none and this leads to execution of

date +%d-%m-%Y --date=" day"

Observe that if you assign NR shell variable, it will use e.g.

NR=100 && echo "$(date +%d-%m-%Y --date="$NR day")"

it will output 100 day after today.

If you does not have to use awk AT ANY PRICE then please consider using bash, for example by doing following, let file.txt content be

offset=0
while read line
do
   echo $line $(date +%d-%m-%Y --date="$offset day")
   offset=$((offset+1))
done < file.txt

gives output (at 15-02-2025)

A 15-02-2025
B 16-02-2025
C 17-02-2025

Explanation: I use while to iterate over lines of file.txt and increase offset by 1 in each turn, after outputting line followed by desired date.

This, using GNU awk for time functions, might be what you're trying to do:

$ awk '{print strftime("%d-%m-%Y", systime()+(NR-1)*86400), $0}' file
16-02-2025 A
17-02-2025 B
18-02-2025 C

It really depends what the output should look like for input line numbers past the end of the range of valid dates for this month, e.g. do you want the output to be valid dates:

16-02-2025 A
17-02-2025 B
...
28-02-2025 M
01-03-2025 N

as the above would output or do you want invalid dates as you'd get by just keeping incrementing the first number:

16-02-2025 A
17-02-2025 B
...
28-02-2025 M
29-02-2025 N

You should really consider printing dates in ISO 8601 format, though, so they're easier to further process (e.g. sort or select lines before/after):

$ awk '{print strftime("%F", systime()+(NR-1)*86400), $0}' file
2025-02-16 A
2025-02-17 B
2025-02-18 C

FYI the answers that call the Unix command date inside a shell loop or inside an awk script would be orders of magnitude slower than the GNU awk answers that use builtin time functions.

发布评论

评论列表(0)

  1. 暂无评论