Skip to content

Instantly share code, notes, and snippets.

@tovask
Created December 30, 2019 14:52
Show Gist options
  • Save tovask/d884efadd5cd81864be784ce07b7d89e to your computer and use it in GitHub Desktop.
Save tovask/d884efadd5cd81864be784ce07b7d89e to your computer and use it in GitHub Desktop.
convert contact list (a VCF file) to CSV format, and back
#!/bin/bash
printerror() { cat <<< "$@" 1>&2; }
totalcount=0
content=$(cat $1)
while read line; do
#echo $line
((totalcount++))
if [ `echo $line | tr -dc '|' | wc -c` -ne 3 ]; then # check separator count
printerror "\n----- WARNING: unexpected separator: " $line " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
fi
if [ `echo $line | tr -dc '"' | wc -c` -ne 8 ] || [[ "${line:0:1}" != "\"" ]] || [[ "${line: -1:1}" != "\"" ]]; then # check quotes
printerror "\n----- WARNING: unexpected quote: " $line " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
fi
if [ `echo $line | tr -dc ';' | wc -c` -ne 4 ]; then # check semicolon count
printerror "\n----- WARNING: unexpected semicolon: " $line " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
fi
line=$(echo $line | tr -d '"') # or echo ${line//\"}
decoded=$(echo $line | cut -d"|" -f1)
telephone=$(echo $line | cut -d"|" -f2)
names=$(echo $line | cut -d"|" -f3)
full_name=$(echo $line | cut -d"|" -f4)
#echo ${decoded} $'\t' ${telephone} $'\t' ${names} $'\t' ${full_name}
encoded=false
if [ `echo -n ${names//[^=]} | wc -c` -gt 0 ] || [ `echo -n ${full_name//[^=]} | wc -c` -gt 0 ] ; then
encoded=true
fi
if [ "$encoded" = true ] && [[ "$decoded" = "$full_name" ]]; then
printerror "\n----- WARNING: unexpected equals sign (=) : " $line " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
fi
#continue
echo "BEGIN:VCARD"
echo "VERSION:2.1"
if [ "$encoded" = false ]; then
echo "N:${names}"
echo "FN:${full_name}"
else
echo "N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:${names}"
echo "FN;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:${full_name}"
fi
echo "TEL;CELL:${telephone}"
echo "END:VCARD"
done <<< "$content"
echo
printerror $totalcount contact processed
#!/bin/bash
totalcount=0
uniformcheck=0
content=$(cat $1)
content=$(echo "$content" | sed -r ':a;N;$!ba;s/=(\r(\n)?|\n(\r)?)//g') # remove '=\n'
while read line; do
#echo $(xxd -pu <<< "$line")
line="${line//[$'\r\n']}" # clear from newline and carriage return
#echo $line
#echo $uniformcheck
((uniformcheck++))
if [[ "$line" = "BEGIN:VCARD" ]]; then # This is the begining of the card
((totalcount++))
if [ $uniformcheck -ne 1 ]; then
echo -e "\n----- WARNING: BEGIN uniformcheck failed: " $uniformcheck " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
fi
fi
if [[ "$line" = "N"* ]]; then # names (e.g. N:Lili;Dorsum;Mueller;;)
names=${line#*:}
#echo -ne "\t" && echo $names
if [[ "$line" = *"CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE"* ]]; then
# in case of encoded (e.g. ;=54=C3=B3=74=68=20=4B=6F=72=6E=C3=A9=6C;;;)
decoded=`echo $line | cut -d: -f2 | awk "BEGIN {FS=\\";\\"} { print \\$1 \\$2 \\$3 \\$4 }" | sed 's/=/\\\\x/g' | xargs -0 printf "%b"`
#echo -ne "\t" && echo $decoded
fi
fi
if [[ "$line" = "FN"* ]]; then # full name (e.g. FN:Dorsum Mueller Lili)
full_name=${line#*:}
#echo -ne "\t" && echo $full_name
if [[ $decoded = "" ]]; then
decoded=$full_name
fi
fi
if [[ "$line" = "TEL"* ]]; then # phone number (e.g. TEL;CELL:+36301234567)
if [[ "$line" != "TEL;CELL"* ]] && [[ "$line" != "TEL;HOME"* ]] && [[ "$line" != "TEL;WORK"* ]] && [[ "$line" != "TEL;VOICE"* ]]; then
echo -e "\n----- WARNING: unknown TEL type: " ${line} " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
fi
# len=$(expr ${line#*:} : '.*') # check the phone number length
# if [[ $len != 12 ]] && [[ $len != 11 ]]; then
# echo -e "\n----- WARNING: TEL length bad: " ${line#*:} $(expr ${line#*:} : '.*') ${decoded} " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
# fi
# if [[ ! "${line#*:}" =~ ^\+36.* ]]; then
# echo -e "\n----- WARNING: TEL start bad: " ${line#*:} ${decoded} " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
# fi
if [ -n "$telephone" ]; then
echo -e "\n----- WARNING: TEL already set: " ${line#*:} ${decoded} " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
if [[ "$telephone" = "${line#*:}" ]]; then
echo -e "\t\t\t\tbut is't the same"
fi
((uniformcheck--))
telephone="${telephone};${line#*:}"
else
telephone=${line#*:}
fi
#echo -ne "\t" && echo $telephone
fi
if [[ "$line" = "END:VCARD" ]]; then # This is the end of a card
csvline="\"${decoded}\"|\"${telephone}\"|\"${names}\"|\"${full_name}\""
if [ -z "$decoded" ] || [ -z "$names" ] || [ -z "$full_name" ] || [ -z "$telephone" ] ; then
echo -e "\n----- WARNING: empty value: " $csvline " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
fi
decoded=""
names=""
full_name=""
telephone=""
echo $csvline
if [ `echo ${csvline//[^\|]} | tr -dc '|' | wc -c` -ne 3 ]; then # check if the original string contains my sepatarot too
echo -e "\n----- WARNING: unexpected number of separator: " $csvline " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
fi
if [ `echo $csvline | tr -dc '"' | wc -c` -ne 8 ]; then # check if the original string contains some quote too
echo -e "\n----- WARNING: unexpected number of quotes: " $csvline " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
fi
if [ $uniformcheck -ne 6 ]; then
echo -e "\n----- WARNING: END uniformcheck failed: " $uniformcheck " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
echo -e "\t\t\t\t\t\t" $csvline
fi
uniformcheck=0
fi
done <<< "$content"
echo
if [ $uniformcheck -ne 0 ]; then
echo -e "\n----- WARNING: finish uniformcheck failed: " $uniformcheck " !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
fi
#echo $totalcount contact processed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment