5

Let's say I have a CSV file:

"col1","col2","col3"
"col4","col5,subtext","col6

The problem I have is as follows :

cut -d, -f1,2 test.txt
"coll1","col2"
"col4","col5

The desired output is :

"col1","col2"
"col4","col5,subtext"
1
  • @iruvar, thanks, neat solution, but unfortunately the script also needs to work on OS X (i.e. BSD) and so I can't assume gawk is available, unfortunatley. Oct 27, 2016 at 12:44

4 Answers 4

5

The ParseWords module, which ships with Perl, covers this quite elegantly. Example below.

$ perl -MText::ParseWords -nE '@a=quotewords ",",1,$_;say $a[0],",",$a[1]' <test.txt
"col1","col2"
"col4","col5,subtext"
$
4

If you have gawk v4 available, a fine solution exists at Parse a csv using awk and ignoring commas inside a field

Example:

gawk -vFPAT='[^,]*|"[^"]*"' '{print $1 "," $2}' test.txt
2
  • The script also needs to work on OS X (i.e. BSD) and so I can't assume gawk is available, unfortunatley. Oct 27, 2016 at 12:43
  • Perl to the rescue perhaps, see my other answer.
    – steve
    Oct 27, 2016 at 13:04
4

Another perl solution, assuming all fields are quoted

$ perl -F'/"\K,(?=")/' -lane 'print "$F[0],$F[1]"' test.txt 
"col1","col2"
"col4","col5,subtext"
  • -F'/"\K,(?=")/' field separator is comma only if it is preceded by " and followed by "
  • print "$F[0],$F[1]" print first two fields separated by ,


Can be done with grep as well

$ grep -oE '^"[^"]*","[^"]*"' test.txt 
"col1","col2"
"col4","col5,subtext"

If N number of fields are needed, use grep -oE '^("[^"]*",){1}"[^"]*"' where the number inside {} is N-1

2

you can also try this with awk as below;

awk -F'","'  '{printf "%s\",\"%s\"\n", $1, $2 }' test.txt 

Eg;

user@host$ awk -F'","'  '{printf "%s\",\"%s\"\n", $1, $2 }' test.txt 
"col1","col2"
"col4","col5,subtext"

You must log in to answer this question.

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