Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Only thing I want to know is on how to format the date with the same awk command. Tried with

awk -F , '{print $3"|"$(date -d 4)","$8 +%Y-%m-%d}' in_t.txt

Getting syntax error. Can I please get some help on this?

$(date -d 4) is not calling the date command nor doing anything outside of the awk program. It is simply concatenating two empty strings with "4" and using the $ to take the value of the 4th field, as you're seeing in the output. – jas Jul 8, 2016 at 9:31 You've asked 40 questions on this forum so far. Why are you now running around posting the same comment under multiple answers, none of which even provided the code in your comment, and under this 5-year-old question containing a new question instead of simply asking your 41st question? This is even worse than the usual chameleon questions! If you have a followup question to ask then simply post a question, reference your existing one if that's useful – Ed Morton Jun 30, 2021 at 18:09 while IFS=',' read -ra arr; do printf "%s|%s,%s\n" "${arr[2]}" $(date -d "${arr[3]}" '+%Y-%m-%d') "${arr[7]}" done < file SSS|2016-10-20,5 AAA|2016-07-20,5 awk -F, '{print | "date -d "$4" \"+%Y-%m-%d\","$1","$8}' in_t.txt. Got this solution working. I want to understand more details on this. What does adding | inside print signify? Also $1 and $8, how to add it before date command? – Programmer Jun 30, 2021 at 18:01 | is just a delimiter in output after SSS. Since I didn't provide an awk answer here to cannot explain that in this answer. – anubhava Jun 30, 2021 at 18:10

What's your definition of a single command? A call to awk is a single shell command. This may be what you want:

$ awk -F'[,-]' '{ printf "%s|20%02d-%02d-%02d,%s\n", $3, $6, (match("JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC",$5)+2)/3, $4, $10 }' file
SSS|2016-10-20,5
AAA|2016-07-20,5

BTW it's important to remember that awk is not shell. You can't call shell tools (e.g. date) directly from awk any more than you could from C. When you wrote $(date -d 4) awk saw an unset variable named date (numeric value 0) from which you extracted the value of an unset variable named d (also 0) to get the numeric result 0 which you then concatenated with the number 4 to get 04 and then applied the $ operator to to get the contents of field $04 (=$4). The output has nothing to do with the shell command date.

awk -F, '{print | "date -d "$4" \"+%Y-%m-%d\","$1","$8}' in_t.txt. Got this solution working. I want to understand more details on this. What does adding | inside print signify? Also $1 and $8, how to add it before date command? – Programmer Jun 30, 2021 at 18:00
awk -v var="20-OCT-16" '
BEGIN{
  split("JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC", month, " ")
  for (i=1; i<=12; i++) mdigit[month[i]]=i
  m=toupper(substr(var,4,3))
  dat="20"substr(var,8,2)"-"sprintf("%02d",mdigit[m])"-"substr(var,1,2) 
  print dat
2016-10-20

Explanation:

Prefix 20 {20}
Substring from 8th position to 2 positions {16}
Print - {-}
Check for the month literal (converting into uppercase) and assign numbers (mdigit) {10}
Print - {-}
Substring from 1st position to 2 positions {20}

This may work for you also.

awk -F , 'BEGIN {months = "  JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"}
    { num = index(months, substr($4,4,3)) / 3
    if (length(num) == 1) {num = "0" num}
    date = "20" substr($4,8,2) "-" num "-" substr($4,1,2)
    print $3"|" date "," $8}' in_t.txt

You were close with your call to date. You can indeed use it with getline to parse and output the date value:

awk -F',' '{
parsedate="date --date="$2" +%Y-%m-%d"
parsedate | getline mydate
close(parsedate)
print $3"|"mydate","$8

Explanation:

  • -F',' sets the field separator (delimiter) to comma
  • parsedate="date --date="$2" +%Y-%m-%d" leverages date's ability to convert the 2nd field to a given output format and assigns that command to the variable "parsedate"
  • parsedate | getline mydate runs your custom "parsedate" command, and assigns the output to the mydate variable
  • close (parsedate) prevents certain errors with multiline input/output (See Running a system command in AWK for discussion of getline and close())
  • print $3"|"mydate","$8 outputs the contents of the original line separated by pipe and comma with the new "mydate" value substituted for field 2.
  • Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.