Using Raku (formerly known as Perl_6)
~$ raku -pe 's:r:nth(1,4,6)/ [ <( <-[,]>* )> \,? ]+? /"$<>"/;' file
#OR
~$ raku -pe 's:r:nth(1,4,6)/ [ <( $<col> = <-[,]>* )> \,? ]+? /"$<col>"/;' file
Sample Input:
a1,b1,c1,d1,e1,f1
a2,b2,c2,d2,e2,f2
a3,b3,,d3,,
a4,b4,,,,
Sample Output:
"a1",b1,c1,"d1",e1,"f1"
"a2",b2,c2,"d2",e2,"f2"
"a3",b3,,"d3",,""
"a4",b4,,"",,""
Above answers are coded in Raku, a member of the Perl-family of programming languages. The example substitution is performed on the 1st, 4th, and 6th (last) columns of a Sample Input, to make sure each is properly quoted. Also, an advantage of the regex above is it will correctly handle cases where column values are empty (lines 3 and 4 of the Sample Input above).
Reading the first regex above, for the :nth(1,4,6)
first and fourth and sixth instances of the pattern <-[,]>*
zero-or-more non-comma containing characters (an empty/non-empty column) are slated to become the match object, since that pattern is encased in <(
...)>
Capture Markers, which drop all recognition elements outside.
From here, the regex demands that the column element is actually followed by \,?
zero-or-one comma, and this column/comma group (denoted by square brackets) is frugally (+?
) repeated one-or-more times. By setting the regex such that the comma is \,?
zero-or-one, the last column is properly handled.
The regex above (for efficiency reasons) can be set to "non-backtracking" using the :r
or :rachet
adverb (a ratchet only moves in one direction). To clarify what the regex is doing, named regexes can be used (example 2), e.g. assigning each column to the $<col>
named-regex. [Finally, similar to other answers, the code only handles "Simple-CSV" and is not designed to handle embedded newlines or commas].
https://docs.raku.org/language/regexes
https://raku.org
a3,b3,,d3,,
?