why isn't awk printing all records?

0
$ awk --version
GNU Awk 3.1.7

Here is my input:

$ cat haldvr.txt StorageHandle: 0xDEADBEAFDEAD0001 av files count: 3 record[0]: id: 0xB91EDF42 name : '' time_cr : 0x5B0F5722 size_bytes : 0x000000007249D25C size_seconds : 0x00000705 bit_rate : 0x00000000 attributes : 0x00000004 record[1]: id: 0x8F65A842 name : '' time_cr : 0x5B060E92 size_bytes : 0x00000000E692A554 size_seconds : 0x00000E0C bit_rate : 0x00000000 attributes : 0x00000004 record[2]: id: 0x9B516A42 name : '' time_cr : 0x5B08B192 size_bytes : 0x00000001E3C17DAA size_seconds : 0x00001C1E bit_rate : 0x00000000 attributes : 0x00000004 haldvr ls finished -> 0

Here is the output I want (or something very similar):

StorageHandle: 0xDEADBEAFDEAD0001 av files count: 3 Record ID Name Time Mbytes Length 0 0xB91EDF42 '' 2018-05-30 08:00:02 1828.61 29:57 1 0x8F65A842 '' 2018-05-23 07:00:02 3689.17 59:56 3 0x9B516A42 '' 2018-05-25 07:00:02 7740.09 59:58

Here is my attempt:

$ cat bin/haldvr1.awk
#!/bin/awk -f
BEGIN           {print("Record\tID\tName\tDate\tMbytes\tLength\n")}
/StorageHandle/ {print $0}
/av files/      {print $0}
/record/        {record=$1}
/name/          {name=$3}
/time_cr/       {time_cr=$3}
/size_bytes/    {mbytes=$3}
/size_seconds/  {dur=$3}
/bit_rate/      {bitrate=$3}
/attributes/    {attributes=$3}
END             {printf("%s\t%s\t%s\t%f\t%s\n",record,id,strftime("%F %T",strtonum(time_cr)),strtonum(mbytes)/1024/1024,strftime("%M:%S",strtonum(dur)))}

Here is my result:

$ cat haldvr.txt | bin/haldvr1.awk
Record  ID      Name    Date    Mbytes  Length

StorageHandle: 0xDEADBEAFDEAD0001
av files count: 3
record[2]:              2018-05-25 19:00:02     7740.093180     59:58

Why is it only printing 1 record instead of 3?

I'll fix the formatting later. But I don't understand why only 1 record is being printed out.

awk
asked on Stack Overflow Jun 13, 2018 by Mannix

2 Answers

0

I would suggest this:

BEGIN { OFS="\t" }
function print_record() {
    if ("id" in rec) {
        if (! printed_header) {
            print "Record","ID","Name","Time","Mbytes","Length"
            printed_header = 1
        }
        print rec["num"], \
              rec["id"], \
              rec["name"], \
              strftime("%F %T", strtonum( rec["time_cr"] )), \
              strtonum( rec["size_bytes"] ) / 1024 / 1024, \
              strftime("%M:%S", strtonum( rec["size_seconds"] ))
        delete rec
    }
}
$1 == "StorageHandle:" || $1 == "av" {print; next}
/^record/ {
    print_record()
    if (split($0,a,/[][]/)) { rec["num"] = a[2] }
    rec["id"] = $NF
}
/^[[:blank:]]/ { rec[$1] = $3 }
END {print_record()}

outputs

awk -f haldvr1.awk haldvr.txt 
StorageHandle: 0xDEADBEAFDEAD0001
av files count: 3
Record  ID      Name    Time    Mbytes  Length
0       0xB91EDF42      ''      2018-05-30 22:00:02     1828.61 29:57
1       0x8F65A842      ''      2018-05-23 21:00:02     3689.17 59:56
2       0x9B516A42      ''      2018-05-25 21:00:02     7740.09 59:58

For prettier output, you can do:

awk -f haldvr1.awk haldvr.txt | { 
    IFS= read -r h1; echo "$h1"
    IFS= read -r h2; echo "$h2"
    column -t -s $'\t'
}
StorageHandle: 0xDEADBEAFDEAD0001
av files count: 3
Record  ID          Name  Time                 Mbytes   Length
0       0xB91EDF42  ''    2018-05-30 22:00:02  1828.61  29:57
1       0x8F65A842  ''    2018-05-23 21:00:02  3689.17  59:56
2       0x9B516A42  ''    2018-05-25 21:00:02  7740.09  59:58
answered on Stack Overflow Jun 13, 2018 by glenn jackman • edited Jun 13, 2018 by glenn jackman
0

Glenn beat me to the punch but I'll throw out my solution here anyways. Your problem was due to the fact you were only printing at the end, so only the last records information was present to be printed. You need to print every time you hit a new record and at the end to print the last record.

Here is the code I used to make the formatting like you are shooting for.

#!/bin/awk -f
BEGIN {
        FS=": "
        }
/Handle/{print $0}
/count/{print "AV File Counts "$2}
/record/{
        if (arr["id"]!=""){
                printf("%s\t%s\t%s\t%s\t%f\t%s\n",arr["record"],arr["id"],arr["name"],strftime("%F %T",arr["time_cr"]),arr["size_bytes"]/1024/1024,strftime("%M:%S",arr["size_seconds"]))
        }
        else
                print("Record\tID\tName\tDate\tMbytes\tLength")
        arr["id"]=$3
        sub(".*\\[","",$1)
        sub("].*","",$1)
        arr["record"]=$1
        }
$1!~"record"{
        gsub(" ","",$1)
        if($2 ~ "0x") {
                gsub(" ","",$2)
                $2=strtonum($2)
        }
        arr[$1]=$2
}
END {
printf("%s\t%s\t%s\t%s\t%f\t%s\n",arr["record"],arr["id"],arr["name"],strftime("%F %T",arr["time_cr"]),arr["size_bytes"]/1024/1024,strftime("%M:%S",arr["size_seconds"]))
}

Output

StorageHandle: 0xDEADBEAFDEAD0001
AV File Counts 3
Record  ID      Name    Date    Mbytes  Length
0       0xB91EDF42      ''      2018-05-30 20:00:02     1828.613857     29:57
1       0x8F65A842      ''      2018-05-23 19:00:02     3689.165363     59:56
2       0x9B516A42      ''      2018-05-25 19:00:02     7740.093180     59:58
answered on Stack Overflow Jun 13, 2018 by jeffpkamp

User contributions licensed under CC BY-SA 3.0