1

I have a .csv file with multiple lines with the following format:

¬Country¬,¬Year¬,¬Singer¬,¬Song Title¬
¬Japan¬,¬1999¬,¬Utada Hikaru¬,¬First Love¬
¬South Korea¬,¬1999¬,¬Lee Jung Hyun¬,¬Wa¬
...

I can print the information I want with awk. For example

awk -F'¬' '{print $2" - "$4}' Model.csv | tail -n +2

which will result in:

Japan - 1999
South Korea - 1999

I want this to be based on user input in a bash script, where the user can choose which columns to print and in which "format". For example, if I want the output to be

[1999] Utada Hikaru - First Love
[1999] Lee Jung Hyun - Wa

I'd use

awk -F'¬' '{print "["$4"]" " "$6" - "$8}' Model.csv | tail -n +2

However, by using "["$4"]" " "$6" - "$8 as input, awk doesn't read it as a pattern for the print command

 #!/bin/bash
 read -p "Which format? " format
 #User will type here desired print pattern, for example "["$4"]" " "$6" - "$8
 awk -v "var=$format" -F'¬' '{print var}' Model.csv

resulting in

"["$4"]" " "$6" - "$8
"["$4"]" " "$6" - "$8
1
  • Your users might prefer an interface where they specify the tags (column header strings like Country) rather than positional field numbers like $1 to select which fields to print. That'll also decouple the users from the order of the fields making it possible for you to make changes to the CSV layout in future if you have to without impacting your users.
    – Ed Morton
    Commented Jun 12 at 15:10

1 Answer 1

3

From your sample input it looks like your field separator is actually ,, not ¬, and those ¬ characters are being used the way that double quotes (") are used in a standards-compliant CSV (see whats-the-most-robust-way-to-efficiently-parse-csv-using-awk).

Assuming that is the case, this will do what you want in any POSIX awk:

$ cat tst.sh
#!/usr/bin/env bash

read -p "Which format? " format

awk -F'¬,¬' '
    NR > 1 {
        gsub(/^¬|¬$/,"")
        print '"$format"'
    }
' "${@:--}"

and adjusting the field numbers to treat the input as a CSV:

$ ./tst.sh Model.csv
Which format? "["$2"]" " "$3" - "$4
[1999] Utada Hikaru - First Love
[1999] Lee Jung Hyun - Wa

I'm assuming that ¬ and newline cannot appear within fields of your CSV.

Warning: Be aware that the format shell variable is expanding to become part of the body of the awk script before awk sees it so you'll have to be VERY careful with who you allow to use the script and ensure they fully understand awk syntax as, in addition to potentially cryptic errors:

$ ./tst.sh Mode1.csv
Which format? $#
awk: cmd. line:5:       print $#
awk: cmd. line:5:              ^ syntax error

$ ./tst.sh Mode1.csv
Which format? $1 / $4
awk: cmd. line:4: (FILENAME=Mode1.csv FNR=1) fatal: division by zero attempted

it's inviting a code injection vulnerability:

$ ./tst.sh Mode1.csv
Which format? system("echo hello")
hello
0

Personally, I would not do this at all but instead figure out some other interface to let users select fields to print and format to print them in.

5
  • 1
    Thanks A LOT for your effort and for the explanation. That does exactly what I want. And sorry if I've edited the post while you were still writing the answer, as I wanted to make it more clear as seen in the answer by @terdon. The ¬ is there instead of " because some songs have " in the title, and I thought that could break something, so I chose a different separator. I saw your comment about using the column header. That's also a great idea, how is it done?
    – baiserekku
    Commented Jun 12 at 15:16
  • You're welcome. The standard way to handle "s within a field is to double the "s so a song title like This "IS" a song gets stored in the CSV as "This ""IS"" a song". Ask a new question about using the column header (and using the standard CSV format unless there's some reason why that won't work for you). Do take a look at the Q&A I linked first though as you may be able to figure everything out for yourself after reading that.
    – Ed Morton
    Commented Jun 12 at 15:23
  • I just added a section to that SO answer under "To print fields from a CSV by the column header names rather than field numbers" to show how to do that.
    – Ed Morton
    Commented Jun 12 at 15:32
  • 1
    Thanks! I was able to do it!
    – baiserekku
    Commented Jun 12 at 19:55
  • This well-written answer expresses serious concerns about code injection vulnerability. I'm certain I saw an answer from @terdon which expressed similar strong (and in my mind--valid) opinions, concluding that prompting for user input should be disfavored. Please I hope that answer will be re-posted, or the extant (one) answer will be updated to include links warning of the dangers of prompting for user input. Thx. Commented Jun 13 at 20:32

You must log in to answer this question.

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