2

I have the following awk code. It first determines the field numbers of interest in the header line and then it prints the output of those fields. The issue is that I am using an associative array to keep the field numbers of interest and thus I print out in the for loop and not using print but rather printf. Its problem is that it adds the separator also at the end of the line.

Is there any simple way around this (without e.g. running through the output again and removing the additional separators)? Or is there a better way to print out the fields the numbers of which are stored in an array?

awk '
    BEGIN {
        FS = ","; OFS = ","
        no_headers = 2; headers[1] = "header1"; headers[2] = "header3"
        k = 0
    }

    NR==1 {
        for (i=1; i<=no_headers; i++) {
            for (j=1; j<=NF; j++) {
                s = gensub(/"/, "", "g", $j)
                if (s==headers[i]) { col_no[++k] = j }
            }
        }
    }

    NR>1 {
        for (i=1; i<=k; i++) { printf "%s,", $col_no[i] }
        print ""
    }' test_awk.txt

a test file looks like this

"header1","header2","header3","header4"
"a","b","c",4
1,"b",,"d"
"a","2","c","d"

and my output at present looks like this

"a","c",
1,,
"a","c",

but I want it to look like this (i.e., no trailing delimiters)

"a","c"
1,
"a","c"
1
  • I commend your wanting to do this with awk (and I am personally very fond of awk!), but Miller might save you some time and effort here: mlr --csv cut -f header1,header3 test_awk.txt. Miller will respect the header row even through sorting and filtering, and will account for many special cases (like commas and quotes inside a field) that you'd otherwise have to handle in your Awk program. Look at the --quote-original and related options in the manual page if you need the quotes in your output.
    – Kevin E
    Jul 23, 2020 at 13:30

1 Answer 1

2

Modify your printf() statement to remove the , from the format specifier and add it inside the {..} part. Use a ternary operator to append the , if not for the last field

printf "%s", (i==k) ? $col_no[i] : $col_no[i]","
1
  • Even […] $col_no[i] OFS should work, avoiding hard-coding the separator, since it's already defined at the top. Great tip!
    – Kevin E
    Jul 23, 2020 at 17:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .