]> git.plutz.net Git - confetti/blobdiff - pdiread.sh
portable sed usage
[confetti] / pdiread.sh
index d2eb9fa2501b30cbf4eeed78fd93d87513d0505f..08fbaec3fb373c2fbb6cdde7974caaa520b849e3 100755 (executable)
@@ -26,8 +26,23 @@ include_pdi="$0"
 BR='
 '
 
 BR='
 '
 
+unescape() {
+  local unescape='s;(^(\\\\)*|[^\\](\\\\)*)\\n;\1\n;g; s;\\(.);\1;g'
+  if [ $# -eq 0 ]; then
+    sed -E "$unescape"
+  else
+    printf %s "$*" \
+    | sed -E "$unescape"
+  fi
+}
+
 pdi_load() {
 pdi_load() {
-  sed -En '
+  # normalise PDI file for processing with pdi_* functions
+  # functions in this library can only be applied to normalised data
+  # Usage example:
+  # data="$(pdi_load file.vcf)"
+
+  sed -srn '
     # === Read entire file into buffer ===
     :X $bY; N; bX; :Y s;^.*$;\n&\n;;
 
     # === Read entire file into buffer ===
     :X $bY; N; bX; :Y s;^.*$;\n&\n;;
 
@@ -51,7 +66,7 @@ pdi_load() {
 
     # === Unscramble aggregated fields ===
     :disag
 
     # === Unscramble aggregated fields ===
     :disag
-    s;\n([^:]+:)((.*[^\])?(\\\\)*),;\n\1\2\n\1;;
+    s;\n([^:\n]+:)(([^\n]*[^\])?(\\\\)*),;\n\1\2\n\1;;
     t disag;
 
     # === Insert FN when only N is present ===
     t disag;
 
     # === Insert FN when only N is present ===
@@ -95,7 +110,7 @@ pdi_load() {
     # === Update obsolete LABEL property ===
     s;\nLABEL((\;[A-Za-z0-9-]+|\;[A-Za-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):(.*)\n;\nADR\1\;LABEL="\5":\n;g;
 
     # === Update obsolete LABEL property ===
     s;\nLABEL((\;[A-Za-z0-9-]+|\;[A-Za-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):(.*)\n;\nADR\1\;LABEL="\5":\n;g;
 
-    p;' "$1"
+    p;' "$@"
 }
 
 pdi_count(){
 }
 
 pdi_count(){
@@ -109,13 +124,31 @@ pdi_count(){
 }
 
 pdi_attrib(){
 }
 
 pdi_attrib(){
-  local card=":$1" name="$2" cnt="${3:-1}"
+  local card=":$1" name="$2" cnt="${3:-1}" attr="$4"
   while [ $cnt -gt 0 ]; do
     [ "${card#*${BR}${name};}" = "$card" ] && return 1
     card="${card#*${BR}${name};}"
     cnt=$((cnt - 1))
   done
   while [ $cnt -gt 0 ]; do
     [ "${card#*${BR}${name};}" = "$card" ] && return 1
     card="${card#*${BR}${name};}"
     cnt=$((cnt - 1))
   done
-  printf %s\\n "${card%%:*}"
+  card="${card%%:*}"
+  if [ "$attr" ]; then
+    case $card in
+      *\;"$attr"=*) card="${card#*;${attr}=}";;
+      "$attr"=*) card="${card#${attr}=}";;
+      "$attr"|*\;"$attr"|"$attr"\;*|*\;"$attr"\;*) return 0;;
+      *) return 1;;
+    esac
+    case $card in
+      \"*\"\;*|\'*\'\;*)
+        card="${card#[\"\']}"; card="${card%%[\"\'];*}"
+        ;;
+      \"*\"|\'*\')
+        card="${card#[\"\']}"; card="${card%%[\"\']}"
+        ;;
+      *\;*) card="${card%%;*}";;
+    esac
+  fi
+  printf %s\\n "${card}"
 }
 
 pdi_value(){
 }
 
 pdi_value(){
@@ -132,7 +165,7 @@ pdi_update_value(){
   local card="${BR}$1" name="$2" cnt="$3" val="$4"
   while [ "$cnt" -gt 0 ]; do
     if [ "${card#*${BR}${name};*:}" = "${card}" ]; then
   local card="${BR}$1" name="$2" cnt="$3" val="$4"
   while [ "$cnt" -gt 0 ]; do
     if [ "${card#*${BR}${name};*:}" = "${card}" ]; then
-       printf '%s\n%s;:' "${card%${BR}END:VCARD*}" "${name}"
+       printf '%s\n%s;:' "${card%${BR}END;:VCARD*}" "${name}"
        card="${BR}END;:VCARD"
        break;
     else
        card="${BR}END;:VCARD"
        break;
     else
@@ -143,6 +176,21 @@ pdi_update_value(){
     fi
     cnt=$((cnt - 1))
   done
     fi
     cnt=$((cnt - 1))
   done
-  printf '%s\n' "$val"
-  printf '%s\n' "${card#*${BR}}"
+  printf '%s\n%s\n' "$val" "${card#*${BR}}"
+}
+
+pdi_update_attrib(){
+  local card="${BR}$1" name="$2" cnt="$3" val="$4"
+  while [ "$cnt" -gt 0 ]; do
+    if [ "${card#*${BR}${name};*:}" = "${card}" ]; then
+       printf '%s\n%s;' "${card%${BR}END;:VCARD*}" "${name}"
+       card=":${BR}END;:VCARD"
+       break;
+    else
+       printf '%s\n%s;' "${card%%${BR}${name};*}" "${name}"
+       card="${card#*${BR}${name};}"
+    fi
+    cnt=$((cnt - 1))
+  done
+  printf '%s:%s\n' "$val" "${card#*:}"
 }
 }