Bash/Shell | How to prioritize quote from IFS in read -
this question exact duplicate of:
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:
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.
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
Post a Comment