BOK_in_NEPA has asked for the wisdom of the Perl Monks concerning the following question:

I am looking for a perl one liner to do an edit in place on a comma delimited file so that every field in the file gets double quoted.. I have been searching the interweb for hours and have not found anything useful.. Sample Line: Joe,43,anytown,anystate,zipcode Desired result: "Joe","43","anytown","anystate","zipcode"
  • Comment on One Liner to double quote every field in a delimited file

Replies are listed 'Best First'.
Re: One Liner to double quote every field in a delimited file
by Tux (Canon) on Jan 31, 2014 at 21:43 UTC

    I am still testing, but the next release of Text::CSV_XS will offer that as

    $ perl -MText::CSV_XS=csv -we'csv (in => csv (file => "file.csv"), out + => *STDOUT, always_quote => 1)'

    I expect to release somewhere next week.

    A longer one-liner that works with Text::CSV_XS right now is:

    $ perl -MText::CSV_XS -we'$c=Text::CSV_XS->new;$a=$c->getline_all(\*AR +GV);$c->eol($/);$c->always_quote(1);$c->print(\*STDOUT,$_)for@$a' fil +e.csv

    Enjoy, Have FUN! H.Merijn
Re: One Liner to double quote every field in a delimited file
by davido (Cardinal) on Jan 31, 2014 at 22:01 UTC

    Here's another Text::CSV or Text::CSV_XS version:

    perl -MText::CSV -lpe 'BEGIN{$c=Text::CSV->new({always_quote=>1})} $c- +>parse($_); $c->combine($c->fields); $_=$c->string' textfile.csv

    ...or a little more brief...

    perl -MText::CSV -lne 'BEGIN{$c=Text::CSV->new({always_quote=>1})} $c- +>parse($_); $c->print(\*STDOUT,[$c->fields])' textfile.csv

    Just substitute "Text::CSV_XS" for Text::CSV if you prefer the XS version, though it's probably not going to make much difference in one-liner world. Watch out for newlines embedded in the input CSV. ;)

    An even better one liner would be to convert whichever version like to an actual script, save it in your path somewhere, and then invoke it as:

    cat infile.csv | quotecsv > newfile.csv

    Dave

Re: One Liner to double quote every field in a delimited fle (Updated!)
by BrowserUk (Patriarch) on Jan 31, 2014 at 21:24 UTC

    perl -pe"s[,][\",\"]g;s[^][\"];s[$][\"];" infile > outfile

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      -- because it does not work:

      $ perl ./browseruk.pl "Joe","43,anytown,anystate,zipcode"

      You forgot a "g" modifier.


      s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
      +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
        You forgot a "g" modifier.

        Indeed I did. Thanks. Now corrected.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

      It's a common mistake to forget to escape literal occurrences of the same character used to "quote" fields.

      Windowsish

      perl -pe "s{(?=\")}{\"}g; s{,}{\",\"}g; s{^}{\"}; s{$}{\"};" infile.csv > outfile.csv

      Unixish

      perl -pe 's{(?=")}{"}g; s{,}{","}g; s{^}{"}; s{$}{"};' infile > outfile
        It's a common mistake to forget to escape literal occurrences of the same character used to "quote" fields.

        I didn't forget.

        I just didn't make the mistake of over-engineering a one-liner to cater for unspecified requirements.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
      Awesome!! Thanks! I wasn't sure how to combine multiple statements into one command..
        sub one_command { ... multiple statements here ... }
Re: One Liner to double quote every field in a delimited file (perl -lanse)
by Anonymous Monk on Jan 31, 2014 at 23:08 UTC
    $ perl -F, -lanse " print join q{,}, map { qq{\x22$_\x22} } @F " ro,sham,bo "ro","sham","bo"
Re: One Liner to double quote every field in a delimited file
by Skeeve (Parson) on Feb 01, 2014 at 15:38 UTC

    Just curious: How would you quote this?

    Joe,43,anytown,anystate,zipcode,71",40°26'47"N 079°58'36"W

    s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
    +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
      Joe,43,anytown,anystate,zipcode,"71""","40°26'47""N 079°58'36""W"

      or

      "Joe","43","anytown","anystate","zipcode","71""","40°26'47""N 079°58'36""W"

      Enjoy, Have FUN! H.Merijn

        This should work:

        chomp($_=<DATA>); $_= join(',', map { s/"/""/g; '"' . $_ . '"' } split /,/) . "\n";

        s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
        +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e