Bash/Shell | How to prioritize quote from IFS in read -


i'm working hand fill file , having issue parse it. file input file cannot altered, , language of code can't change bash script.

i made simple example make easy ^^

var="hey","i'm","happy, like","you" ifs="," read -r 1 2 tree 5 <<<"$var" echo $one:$two:$tree:$for:$five 

now think saw problem here.

hey:i'm:happy, like:you: 

but get

hey:i'm:happy: like:you 

i need way tell read " " more important ifs. have read eval command can't take risk.

to end directory file , troublesome field description one, have in it.

original file looking that

"type","cn","uid","gid","gecos","description","timestamp","disabled" "type","cn","uid","gid","gecos","description","timestamp","disabled" "type","cn","uid","gid","gecos","description","timestamp","disabled" 

edit #1

i give better exemple; 1 use above simple , @stefanhegny found cause error.

while read -r ldapline                 ifs=',' read -r objectclass dumy1 uidnumber gidnumber username description modifytimestamp nsaccountlock gecos homedirectory loginshell createtimestamp dumy2 <<<"$ldapline"              isanetuser=0              while ifs=":" read -r -a class                                 in "${class[@]}"                                                 if [ "$i" == "account" ]                                                                 isanetuser=1                                     break                             fi                     done             done <<< $objectclass              if [ $isanetuser == 0 ]                                 continue             fi              #more stuff append#      done < file.csv 

so small part of code should explain do. file.csv lot of lines this:

"top:shadowaccount:account:posixaccount","jdupon","12345","6789","jdupon","jean mark, dupon","20140511083750z","","jean mark, dupon","/home/user/jdupon","/bin/ksh","20120512083750z","","" 

if various bash versions use more recent v3.0, when regexes , bash_rematch introduced, use following function: [note 1]

each_field () {     local v=,$1;     while [[ $v =~ ^,(([^\",]*)|\"[^\"]*\") ]];         printf "%s\n" "${bash_rematch[2]:-${bash_rematch[1]:1:-1}}";         v=${v:${#bash_rematch[0]}};     done } 

it's argument single line (remember quote it!) , prints each comma-separated field on separate line. written, assumes no field has enclosed newline; that's legal in csv, makes dividing file lines lot more complicated. if needed deal scenario, change \n in printf statement \0 , use xargs -0 process output. (or insert whatever processing need field in place of printf statement.)

it goes trouble dequote quoted fields without modifying unquoted fields. however, fail on fields embedded double quotes. that's fixable, if necessary. [note 2]

here's sample, in case wasn't obvious:

while ifs= read -r line;   each_field "$line"   printf "%s\n" "-----" done <<eof type,cn,uid,gid,gecos,"description",timestamp,disabled "top:shadowaccount:account:posixaccount","jdupon","12345","6789","jdupon","jean mark, dupon","20140511083750z","","jean mark, dupon","/home/user/jdupon","/bin/ksh","20120512083750z","","" 

eof

output:

type cn uid gid gecos description timestamp disabled ----- top:shadowaccount:account:posixaccount jdupon 12345 6789 jdupon jean mark, dupon 20140511083750z  jean mark, dupon /home/user/jdupon /bin/ksh 20120512083750z   ----- 

notes:

  1. i'm not saying should use function. should use csv parser, or language includes csv parsing library, python. believe bash function work, albeit slowly, on correctly-formatted csv files of common csv dialect.

  2. here's version handles doubled quotes inside quoted fields, classic csv syntax interior quotes:

    each_field () {      local v=,$1;     while [[ $v =~ ^,(([^\",]*)|\"(([^\"]|\"\")*)\") ]];         echo "${bash_rematch[2]:-${bash_rematch[3]//\"\"/\"}}";         v=${v:${#bash_rematch[0]}};     done } 

Comments

Popular posts from this blog

PySide and Qt Properties: Connecting signals from Python to QML -

c# - DevExpress.Wpf.Grid.InfiniteGridSizeException was unhandled -

scala - 'wrong top statement declaration' when using slick in IntelliJ -