1

This is a follow up question to Awk: “Current time” outputs as zero

I am trying to send the first field in file1 and the current time, as two seperate fields, into a .CSV file so that field1 will populate a different cell than field2.

E.g.in file one. a row looks like this:

IN-X_4096_20140802_121306_007 `random text`

[edit:] where in this particular row of file1, the 007 ends the first field, and 'random text' means numerous fields appear in the row along with the first field described above.

[edit:] I want that field 1 is taken from file1 and becomes a cell in the file2.CSV. So column 1 in file2.csv will always be field 1 from file 1. The tricky part seems to be to make column 2 in file2.csv contain the time.

N-X_4096_20140802_121306_007 (cell in column A) 14:24:32 (cell in column B)

The code I am using is:

awk -v OFS=, '{ print $1 strftime(" %r")}' file1.jump > file2.csv

At the moment, this code results in the .CSV file placing the entire output into one cell, for each row, in file2.csv. Is there a way to make the output go into seperate cells in the .CSV?

ZakS
  • 1,073
  • 3
  • 15
  • 27
  • Sorry, but the question is not really clear. Can you give a clear example of what your input is, and how it should look like? Eg. file 1 has lines like "A B C D" and I expect it to have the output like "A,14:24:32,B,C,D" or something like that. – kvantour Oct 17 '18 at 14:01
  • 1
    It is also really good that you atomize your questions! Keep up the good work! – kvantour Oct 17 '18 at 14:03
  • 1
    Change `$1 strftime(" %r")` to `$1, strftime("%r")` – Ed Morton Oct 17 '18 at 14:04
  • 1
    @ZakS Was The solution of EdMorton Correct? – kvantour Oct 17 '18 at 14:10
  • Dear @EdMorton -- it works, thank you. Am I understanding correctly that since OFS=, sets the field operator to a "," -- it therefore outputs as two seperate fields? – ZakS Oct 18 '18 at 06:10
  • @ZakS I have added a bit of information to my answer about your question to EdMorton. – kvantour Oct 18 '18 at 07:32

1 Answers1

1

From your comments it seems that your actual question is:

How does the print statement work and how is it affected by the variable OFS.

First of all, it is important that realize that the two most important concepts to are records and fields.

The input which is fed into awk through various means (stdin or getline) is read record by record where each record is separated by a record separator which is defined by RS. Since RS is by default the <newline> character \n, a record is actually a line and thus awk processes default a file line-by-line.

When a record/line is read, awk will split the record in fields where each field is separated by the field separator FS (which can be a regular expression). By default, the field separator FS is set to be any sequence of <blank> characters. Which means that, by default, each field is a word. If you redefine FS, fields will be different. Eg.

Mooo, that sexy cow!

has 4 fields by default ($1="Mooo,", $2="that", "$3="sexy" and $4="cow!") but if FS="," it only has 2 fields ($1="Mooo" and $2=" that sexy cow!")

The above is all about input and how awk understands it, but also in output the concept of records and fields is known. And this is where the print statement comes in. The print statement allows you to print a record which is build of various fields. The output record separator ORS, by default a <newline> character \n, tells you how two records are separated and the output field separator OFS, by default a <space> , tells you how the fields are separated. The print statement looks like

print arg1, arg2, ..., argn

and will print a record with n fields separated by OFS and ending with ORS.

The print statement shall write the value of each expression argument onto the indicated output stream separated by the current output field separator (see variable OFS above), and terminated by the output record separator (see variable ORS above). All expression arguments shall be taken as strings, being converted if necessary; this conversion shall be as described in Expressions in awk, with the exception that the printf format in OFMT shall be used instead of the value in CONVFMT. An empty expression list shall stand for the whole input record ($0).

source: POSIX Awk

So now to answer the question. Your original line reads:

awk -v OFS=, '{ print $1 strftime(" %r")}' file1.jump > file2.csv

here OFS has no effect as print has only a single argument which reads $1 strftime(" %r") (note that the space between $1 and strftime has no meaning and can be ignored, so both strings are concatenated. So what you want is this:

awk -v OFS=, '{ print $1, strftime("%r")}' file1.jump > file2.csv

original (wrong) answer

I believe what you are after is a combination of:

So you could do it like,

awk '{ print $1,strftime(" %r")}' file | paste -s -d',' > file2

Or if it is just awk only,

awk '{ printf (NR==1?"":",") $1 OFS strftime(" %r") }' file > file2
Community
  • 1
  • 1
kvantour
  • 25,269
  • 4
  • 47
  • 72