• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

(gelöst) komplexerer Dateifilter (google kalender)

Moin moin

ich würde gerne aus meinem Google Kalender Namen und Adressen filtern.

Ich habe eine ics Datei, in der die Zeilen SUMMARY LOCATION und DESCIPTION von Bedeutung sind.
Mit grep -E 'SUMMARY|LOCATION|DESCRIPTION' ./basic.ics bekomme ich diese Infos. Nun möchte ich zusätzlich eine Leerzeile nach jedem Block, den Anfang der Zeilen mit den oben genannten Suchmustern löschen und alle Blöcke in denen LOCATION keine Infos enthält ganz löschen. :???:

Ich bin jetzt nicht so der Krack auf dem Gebiet. Das mit Suchmustern am Anfang würde ich noch hinbekommen. Aber der Rest ? Script ? etc..
Ich würde es ja auch händisch machen, aber es sind einfach zu viele :roll:
Würde mir hier jemand helfen ?

Grüße Hajo
 
Hallo,

Ich denke, um Dir evtl. zu helfen sollte es nicht notwendig sein "Google Kalender" zu kennen.

Poste doch einfach ein Beispiel Deiner "basic.ics" Datei (pers. Daten duch irgend etwas ersetzen).

Du könntest auch ein (konstruiertes) Beispiel zeigen wie Du die Daten letztendlich haben möchtest.

Gruss,
Roland
 
Hallo Sharki,

Sharki schrieb:
Nun möchte ich zusätzlich eine Leerzeile nach jedem Block, den Anfang der Zeilen mit den oben genannten Suchmustern löschen und alle Blöcke in denen LOCATION keine Infos enthält ganz löschen. :???:
Wäre das was?:
http://sed.sourceforge.net/sed1line_de.html schrieb:
# Füge eine Leerzeile unter jeder Zeile ein, die "regex" enthält
sed '/regex/G'

lieben Gruß aus Hessen
 
Hi

also so sieht der Text aus. Zwei Datenblöcke.
BEGIN:VEVENT
DTSTART:20121029T080000Z
DTEND:20121029T090000Z
DTSTAMP:20121027T162014Z
UID:p0lbll3nnqal1lh46ap26js0b4@google.com
CREATED:20121026T153231Z
DESCRIPTION:
LAST-MODIFIED:20121026T153231Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Mustermann
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART:20120131T121500Z
DTEND:20120131T131500Z
DTSTAMP:20121027T162014Z
UID:eek:4odb9lg6lr579rl9sp6udi0b0@google.com
CREATED:20120123T110457Z
DESCRIPTION:0163 2503207\n06071 6038419
LAST-MODIFIED:20121026T153218Z
LOCATION:Donaustraße 12\, Musterhausen
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:Mustermann
TRANSP:OPAQUE
END:VEVENT

Interessant für mich ist der Datensatz nur wenn LOCATION eine Info enthält.
Grüße Hajo
 
Hier ist ein bash script (als Entwurf gedacht... kann sicher verbessert werden):

Code:
#!/bin/bash

# make executable with "chmod 755 scriptname"

# Format of input data:
#
# BEGIN:VEVENT
# DTSTART:20120131T121500Z
# DTEND:20120131T131500Z
# DTSTAMP:20121027T162014Z
# UID:o4odb9lg6lr579rl9sp6udi0b0@google.com
# CREATED:20120123T110457Z
# DESCRIPTION:0163 2503207\n06071 6038419
# LAST-MODIFIED:20121026T153218Z
# LOCATION:Donaustraße 12\, Musterhausen
# SEQUENCE:2
# STATUS:CONFIRMED
# SUMMARY:Mustermann_2
# TRANSP:OPAQUE
# END:VEVENT

# script will extract the fields (output to console):
#
#   SUMMARY
#   LOCATION
#   DESCRIPTION
#
# if LOCATION is non-empty

inputfile=$1

echo
echo --------------------
echo $0
date
echo 'input =' $inputfile
echo

flag=0

cat $inputfile |
while read -r line        # '-r' to preserve escapes ('\n') in DESCRIPTION
do
  if [ $flag -eq 1 ]; then
    echo -n $line | grep "END:VEVENT" > /dev/null
    ret=$?
    if [ $ret -eq 0 ]; then
      if [ ${#location} -ne 0 ]; then
        echo -e $summary
        echo -e $location
        echo -e $description
        echo
      fi
      summary=''
      location=''
      description=''
      flag=0
    else
      echo -n $line | grep "DESCRIPTION:" > /dev/null
      ret=$?
      if [ $ret -eq 0 ]; then
        description=$(echo $line | sed -e "s/[\ \o011]*DESCRIPTION://")
      else
        echo -n $line | grep "LOCATION:" > /dev/null
        ret=$?
        if [ $ret -eq 0 ]; then
          location=$(echo $line | sed -e "s/[\ \o011]*LOCATION://")
          location=$(echo $location | sed -e "s/\o134\o134,/,/")
        else
          echo -n $line | grep "SUMMARY:" > /dev/null
          ret=$?
          if [ $ret -eq 0 ]; then
            summary=$(echo $line | sed -e "s/[\ \o011]*SUMMARY://")
          fi
        fi
      fi
    fi
  elif [ $flag -eq 0 ]; then
    echo -n $line | grep "BEGIN:VEVENT" > /dev/null
    ret=$?
    if [ $ret -eq 0 ]; then
      flag=1
    fi
  fi
done

echo --------------------

# --- end of script ---

Dein Beispiel:

Code:
cat  basic.ics
BEGIN:VEVENT
DTSTART:20121029T080000Z
DTEND:20121029T090000Z
DTSTAMP:20121027T162014Z
UID:p0lbll3nnqal1lh46ap26js0b4@google.com
CREATED:20121026T153231Z
DESCRIPTION:
LAST-MODIFIED:20121026T153231Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Mustermann
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART:20120131T121500Z
DTEND:20120131T131500Z
DTSTAMP:20121027T162014Z
UID:o4odb9lg6lr579rl9sp6udi0b0@google.com
CREATED:20120123T110457Z
DESCRIPTION:0163 2503207\n06071 6038419
LAST-MODIFIED:20121026T153218Z
LOCATION:Donaustraße 12\, Musterhausen
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY:Mustermann
TRANSP:OPAQUE
END:VEVENT
Code:
./extract basic.ics

--------------------
./extract
Wed Oct 31 04:10:17 CET 2012
input = basic.ics

Mustermann
Donaustraße 12, Musterhausen
0163 2503207
06071 6038419

--------------------
(in eine Datei kopieren mit "./extract input.ics > adressen.txt")
(kannst natürlich dem script irgend einen Namen geben)

Gruss,
Roland
 
Hab noch etwas gespielt :D diese Variante gefällt mir etwas besser. Mit 'awk' würde sich die Aufgabe vielleicht mit weniger Code lösen lassen...
Code:
#!/bin/bash

begin_record="BEGIN:VEVENT"
end_record="END:VEVENT"

tags=("SUMMARY" "LOCATION" "DESCRIPTION")

output=([0]='' [1]='' [2]='')

flag=0
k=0;

inputfile=$1

echo
echo ----------------------------------------
echo $0
date
echo 'input =' $inputfile
echo ----------------------------------------
echo

cat $inputfile |
while read -r line        # '-r' to preserve escapes ('\n') in DESCRIPTION
do
  if [ $flag -eq 1 ]; then
    echo -n $line | grep "[\ \o011]*$end_record" > /dev/null
    ret=$?
    if [ $ret -eq 0 ]; then
      if [ ${#output[1]} -ne 0 ]; then
        echo -e ${output[2]}
        echo -e ${output[1]}
        echo -e ${output[0]}
        echo
      fi
      unset output[*]
      flag=0
      k=0;
    else
      for i in "${tags[@]}"; do
        echo -n $line | grep "$i" > /dev/null
        ret=$?
        if [ $ret -eq 0 ]; then
          tmp=$(echo $line | sed -e "s/[\ \o011]*$i://")
          output[$k]=$(echo $tmp | sed -e "s/\o134\o134,/,/")
          let "k += 1"
        fi
      done
    fi
  elif [ $flag -eq 0 ]; then
    echo -n $line | grep "$begin_record" > /dev/null
    ret=$?
    if [ $ret -eq 0 ]; then
      flag=1
    fi
  fi
done

echo ---end of data---

# --- end of script ---
 
A

Anonymous

Gast
RME schrieb:
Mit 'awk' würde sich die Aufgabe vielleicht mit weniger Code lösen lassen...
mit Sicherheit in weniger als 5 Zeilen, ist dann aber nicht so schön les- und verstehbar. ;) nur wesentlich schneller, aber das ist wohl in dieser Aufgabe überhaupt nicht von Bedeutung.

robi
 
Eine awk Lösung:
Code:
#!/bin/bash
filename=$1
awk 'BEGIN{RS="BEGIN:VEVENT\n";FS="\n"}{if(length($8)>9){  print $11; print $8 ;print$6}}' $filename  | awk 'BEGIN{FS=":"} $1=="SUMMARY"{print $2}$1=="LOCATION"{print substr($2,0,index($2,"\\")-1);print substr($2,index($2,",")+2)}$1=="DESCRIPTION"{split($2,t,"\\");for(i in t){if(substr(t[i],0,1)=="n"){print substr(t[i],2)}else{print t[i]}}{print ""}}'

Weil "awk" sehr empfindlich mit Zeilenumbrüchen und dergleichen ist, habe ich dir das File auf meinen Server gelegt.
Mit "wget -O print_ics http://http://interhacktive.de/tempfiles/print_ics" kriegst du die paar Bytes funktionierend auf die Platte.
Ausführbar machen ( chmod +x print_ics ) und aufrufen mit "./print_ics DeinGoogleAdressFile"
Have fun
 
Oben