Here is a ruby with the built-in csv parser to do that. You can both parse and generate proper quoted csv thus:
ruby -r csv -e 'data_in=CSV.parse($<.read, **{:headers=>true})
cron=data_in.headers.select{|h| h[/chronic/i] }
puts CSV.generate{|csv|
([cron] + data_in.values_at(*cron)).each{|row| csv << row}
}
' file
With your example, prints:
chronic_disease1,chronic_disease2
2008,2009
Now suppose an example with quoted fields that would be harder to do with awk
alone.
Given:
gender,chronic_disease1,chronic_disease2
male,2008,"2005, type c"
female,"2010, type b",2009
Prints:
chronic_disease1,chronic_disease2
2008,"2005, type c"
"2010, type b",2009
As an alternate, you can delete the columns the do not match the regex:
ruby -r csv -e 'data_in=CSV.parse($<.read, **{:headers=>true})
data_in.delete(*data_in.headers.select{|h| !h[/chronic/i] })
puts data_in
' file
# same output
Which may be more efficient depending if you have more matches or non-matches in your csv.
Or if you have a HUGE file, processing the csv line by line is certainly more efficient:
ruby -r csv -e '
header=[]
$<.each_with_index{|line,i|
row=CSV.parse(line).flatten
if i==0
row.each_with_index{|e,i| if e[/chronic/i] then header << i end }
end
puts header.map{|i| row[i] }.to_csv
}' file
That version removes columns from a 400MB file into a second file in about 3 minutes.
Just for comparison, here is an awk:
awk '
BEGIN{FS=OFS=","}
NR==1{for(i=1;i<=NF;i++) if ($i~/chronic/) head[++cnt]=i}
{
for(i=1;i<=cnt;i++)
printf "%s%s", $(head[i]), (i<cnt ? OFS : ORS)
}
' file
That processes the same 400MB in about 45 seconds. So with simple csv, awk is better, faster. Throw in a few complexities, Ruby is easier and more robust.