4

Okay, So I have a CSV file of users and passwords, the passwords sometimes contain backslashes, I need to loop over this file and pass the user and password to another script, but I can't figure out how to make bash take the backslash as a literal character.

The csv:

jgalley@debian1mig:~/logs/zimbraShares$ cat test.csv 
user3@domain.com,bzfbx6bkuu\Mpull
user2@domain.com,Hppk8mll\kffbsfd
user1@domain.com,w1fgfqbjlhLjnni\

Sed is not expanding the backslashes - this is good:

jgalley@debian1mig:~/logs/zimbraShares$ cat test.csv | sed "s/,/\t/" 
user3@domain.com        bzfbx6bkuu\Mpull
user2@domain.com        Hppk8mll\kffbsfd
user1@domain.com        w1fgfqbjlhLjnni\

trying to read them into variables causes the backslash to be a meta-character, as you can see, it escapes the characters and also causes the last line to escape the return character since it's on the end:

jgalley@debian1mig:~/logs/zimbraShares$ cat test.csv | sed "s/,/\t/" | while read user pass; do echo "${user},${pass}"; done
user3@domain.com,bzfbx6bkuuMpull
user2@domain.com,Hppk8mllkffbsfd

Trying to escape the backslashes first also doesn't work:

jgalley@debian1mig:~/logs/zimbraShares$ cat test.csv | sed "s/,/\t/" | sed "s/\\\/\\\\/g" | while read user pass; do echo "${user},${pass}"; done
user3@domain.com,bzfbx6bkuuMpull
user2@domain.com,Hppk8mllkffbsfd
jgalley@hoth1mig:~/logs/zimbraShares$ 

The ultimate goal will be do something like this:

head test.csv | sed "s/,/\t/g" | while read auser apass;
do 
  echo -n "${auser},${apass}"
  bash -c  "/home/jgalley/scripts/someScript.php -u '${auser}' -p '${apass}' -d '${auser}'";      
done
jesse_galley
  • 1,676
  • 4
  • 18
  • 30
  • What will do you when a password contains a comma? Parsing CSV in bash is hard. I'd suggest doing this in a language that has a [proper CSV parsing library](http://docs.python.org/2/library/csv.html) – Phil Frost Dec 31 '12 at 17:46
  • The password field contains no commas. Backslashes are the only character giving me trouble. – jesse_galley Dec 31 '12 at 17:48
  • you can avoid sed and greatly simplify things by setting `IFS=,`. See [How to have bash parse a CSV file?](http://stackoverflow.com/questions/4286469/how-to-have-bash-parse-a-csv-file). But I still don't think it's a good idea. – Phil Frost Dec 31 '12 at 17:54

1 Answers1

7

Use the -r option of read:

while read -r auser apass;

If -r is given, the \ won't be considered as an escape character.

P.P
  • 117,907
  • 20
  • 175
  • 238
  • 3
    This is definitely _the_ answer. (Actually, `read` should always be used with the `-r` option, unless you know what you're doing). – gniourf_gniourf Dec 31 '12 at 17:58