{{tag> bash script automatisch sophomorix sophomorix-project vergleichen ersetzen zwei dateien export csv umlaute}} ====== Script zur automatischen Erzeugung von Projekten (z.B. für die Oberstufe) ====== **Das Problem:** In der Schulkonsole kann man bequem Klassen von Jahrgang 5 bis 10 handhaben -- aber Oberstufenkurse müssen immer zunächst "umständlich" zusammen geklickt und dann als Projekt eingerichtet werden, bevor man sie nutzen kann. **Die Lösung:** Die meisten Schulverwaltungsprogramme sind in der Lage, Kurslisten mit den Kurslehrern und allen darin enthaltenden Namen der Schülerinnen und Schüler als CSV-Datei zu exportieren. (Beispiel: [[http://www.nibis.de/nibis.php?menid=3703|Apollon]] -> Datenexport). Der Export umfasst 5 Spalten: **KursID; Vorname des Lehrers; Nachname des Lehrers; Vorname des Schülers; Nachname des Schülers;** Natürlich stehen dort aber die vollständig ausgeschriebenen Namen und nicht die Kürzel des linuxmuster-Servers. Das hier vorgestellte Script untersucht die exportierte Datei und ersetzt die Namen durch die Kürzel des linuxmuster-Servers. Danach werden Projekte angelegt, in denen der betreffende Lehrer als Admin und alle betroffenen Schüler als Mitglieder eingetragen werden. Der Vorteil ist, dass man diese automatisch erzeugten Projekte sowohl für die WLAN-Freigabe einsetzen kann (sofern man z.B. den [[http://www.linuxmuster.net/wiki/anwenderwiki:benutzerrechner:wlan:coovachilli-usermanagement?s[]=wifi|coovachilli]] einsetzt) als auch, dass die Projekte unter moodle als "globale Gruppen" wieder auftauchen und man sie dort //sofort// nutzen kann -- ohne dass man sich vorher alle Schüler seiner Kurse "mühsam" zusammensuchen muss (sofern man das [[http://www.linuxmuster.net/wiki/anwenderwiki:moodle:moodle2_automatische_einschreibung|openlml-Plugin für moodle]] benutzt). Das Script liefert ggf. sehr viele Projekte. Es ist also zu bedenken, ob man diese Projekte wirklich alle eintragen will. Zudem ist das Script nicht "scharf gestellt". Die Erzeugung der sophomorix-Projekte wird also (noch) nicht durchgeführt, sondern nur auf dem Bildschirm ausgegeben. ===== Ergänzung: ===== Die exportierte Datei kann man mit folgendem Script von Umlauten, Bindestrichen und Leerzeichen befreien: **Syntax: ./umlaute_entfernen.sh dateiname.csv** #!/bin/bash #Umlaute, LEERZEICHEN und Bindestriche aus der angehängten CSV-Datei entfernen! filename="${0##*/}" scriptpath=`pwd -P` if [ -z "$1" ] then echo "Syntax: $scriptpath/$filename " exit 0; fi cp $1 $1.bak # safety first sed -i -e 's/\Ä/Ae/g' \ -i -e 's/\ä/ae/g' \ -i -e 's/\Ö/Oe/g' \ -i -e 's/\ö/oe/g' \ -i -e 's/\Ü/Ue/g' \ -i -e 's/\ü/ue/g' \ -i -e 's/\ß/ss/g' \ -i -e 's/-//g' \ -i -e 's/\s//g' \ $1 Mit diesem Befehl konvertiert man eine Datei in das UTF-8-Format: # Recode nach UTF-8: (-f from -t to) # iconv -f ISO-8859-15 -t UTF-8 infile.csv > outfile.csv Das Script ist noch in einem sehr frühen Stadium. Einige Befehle wurden möglicherweise unnötig kompliziert durchgeführt. Verbesserungsvorschläge sind natürlich willkommen! **Syntax: ./globale_gruppen_oberstufe.sh** #!/bin/bash ################################################################################################## #VER 1.0 vom 04.12.2015, M.H. #Keine Umlaute, keine Leerzeichen, keine Bindestriche in Doppelnamen! ################################################################################################## #Dieses Script verwendet exportierte .csv-Daten aus DaNis/Apollon und liest daraus #die Anzahl der vorhandenen Kurse für die Oberstufe aus. #Export-Format: KursID;Lehrervorname;Lehrernachname;Schülervorname;Schülernachname; #(5 Spalten, UTF-8 codiert, keine Umlaute, keine Bindestriche, keine Leerzeichen) #Danach wird mit der von sophomorix-print erzeugten Jahrgangsliste für die Jahrgänge 11 und 12 #verglichen und den Namen werden die entsprechenden Logins zugeordnet. #Am Ende werden Projekte angelegt, in die die entsprechenden Schüler eingetragen werden. #Vorteil: Sowohl für die WLAN-Freigabe als auch unter moodle ist die Verwaltung #von Oberstufenkursen nun möglich! ################################################################################################## #Dieser Abschnitt muss angepasst werden: #Jahrgänge festlegen: (Oberstufe: momentan nur jg-11 und jg-12) jahrgang="jg-11 jg-12" lehrer="teachers" #Dateinamen festlegen: #Dateiname von DaNis/Apollon (vorher Umlaute/Bindestriche/Leerzeichen aus dieser Datei entfernen!): kurse="jg-11-12.csv" ################################################################################################## #Umsortiert zu: kursID="jg-11-12-zusammengefasst.csv" #extrahierte Kursnamen: kursnamen="vorhandene_kurse.csv" #Zuordnungen von Namen zu IDs mit entsprechenden Kurs-IDs: IDs="kursIDs_mit_UserIDs.csv" #Dateiname für sophomorix-print (zusammgenfügte Datei): out="oberstufe_lehrer_sophomorix.csv" ################################################################################################### #Teil I: Vorbereiten der Linuxmuster-Userdaten. Die Jahrgaenge der Oberstufe und die #Lehrer-Logins werden in *eine* Datei gepackt und so formatiert, dass nur noch #Jahrgang;NameVorname;login; auftaucht. print="/var/lib/sophomorix/print-data" #Cleanup: rm -f ./$kursID rm -f ./$kursnamen rm -f ./$IDs rm -f ./$out #User-Daten erzeugen: for i in $jahrgang do sophomorix-print -c $i gawk -F";" '{ print $1";" $2$3";" $4";"}' "$print/"$i"_WebUntis-unix.csv" >> $out done sophomorix-print -t $lehrer gawk -F";" '{ print $1";" $2$3";" $4";"}' "$print/"$lehrer"_WebUntis-unix.csv" >> $out #################################################################################################### #Teil II: Die exportierten Daten von DaNis/Apollon werden eingelesen: #Entfernt bei Bedarf die erste Zeile und schreibt das Ergebnis in kurse2.csv (falls Spaltenüberschriften mit exportiert wurden): #sed '1,1d' $kurse > kurse2.csv #Die Spalten mit Vor-/Nachnamen werden zusammengefasst, um EINE Spalte als Suchbegriff zu erhalten: gawk -F";" '{ print $1";" $3$2";" $5$4";"}' $kurse |sed 's/-//g' > $kursID #Welche unterschiedlichen Kurse gibt es? cat $kursID | cut -d";" -f1 | uniq > $kursnamen #(liefert nur die 1. Spalte und zeigt keine Duplikate) #Vorlage unter: http://unix.stackexchange.com/questions/126485/replacing-the-values-in-one-file-with-the-values-in-another-file-in-bash #Namen durch Logins ersetzen: gawk -F';' 'NR==FNR{a[$2]=$3} NR>FNR{$2=a[$2];$3=a[$3];print}' OFS=',' "$out" "$kursID" > $IDs echo cat $IDs |more echo echo "Liste prüfen! Es dürfen keine Lücken auftauchen!" read -p "Press any key to continue... " ################################################################################################################# #Teil III: Die erzeugte Datei wird zeilenweise eingelesen und die sophomorix-projekte werden automatisch erzeugt: #Wieviele unterschiedliche Kurse sind es? ANZ=$(cat $kursnamen | wc -l) echo echo "Es gibt $ANZ Kurse. Für diese Kurse wird nun jeweils ein Projekt erstellt!" echo "==========================================================================" echo read -p "Press any key to continue... " while IFS="," read kursID lehrer; do echo "#Kurs: $kursID Leitung: $lehrer" echo -n "sophomorix-project -p p_kurs_$kursID --join --create --admins $lehrer --members " while IFS="," read kurs lehrer schueler; do if [[ $kurs == "$kursID" ]]; then echo -n $schueler"," fi done < <(cat $IDs |tr [:upper:]ÄÖÜ [:lower:]äöü ) echo echo "#----------------------------------------------------------------------" done < <(cat $IDs | cut -d"," -f1,2 |uniq |tr [:upper:]ÄÖÜ [:lower:]äöü) #EOF In der Zwischenzeit ist das Script weiter gewachsen. Nun ist es möglich, die anzulegenden Projekte direkt über ein sog. [[http://www.cc-c.de/german/linux/linux-dialog.php|"dialog"-Menu]] aufzurufen. Der Vorteil liegt darin, dass es schneller geht und man nicht unbedingt alle Projekte, die möglich sind, auch wirklich anlegen lassen will. Auf dem Server muss das Paket [[https://wiki.ubuntuusers.de/Dialog|"dialog"]] installiert sein. Das Script liest die zuvor erzeugte Datei "kursIDs_mit_UserIDs.csv" wieder ein und übergibt die Parameter an den sophomorix-project-Befehl. Natürlich kann man auch beide Scripte zu einem großen Tool vereinen. Der Stand der Dinge ist im Moment aber zwei getrennte, lauffähige Scripte zu haben. Wieder gilt, dass das Script nicht scharf gestellt ist und die Befehle nur auf der Bildschirmausgabe ausgegeben werden. Man kann also alles relativ gefahrlos testen! **Syntax: ./project-manager.sh dateiname.csv** #!/bin/bash ####################################################################### # Scriptname : project_manager.sh # Author : Vorlage von Bernd Holzhauer; geändert von M.H. # URL : http://www.cc-c.de/german/linux/linux-dialog.php # Date : 2015-12-19 # Requires : dialog, exportierte CSV-Datei # Category : geeignet für linuxmuster 6.x #Version : VER='1.1' ####################################################################### #Variablen: _temp="/tmp/answer.$$" #PN=`basename "$0"` #echo $PN #dialog >$_temp #DVER=`cat $_temp | head -1` #echo $DVER output="create-projects.csv" output2="kill-projects.csv" outtemp="create_temp.csv" outtemp2="kill_temp.csv" #Einzulesende CSV-Datei (entweder als Paramter übergeben): IDs=$1 #Oder festen Dateinamen zuordnen: #IDs="kursIDs_mit_UserIDs.csv" #Test, ob Syntax richtig angegeben wurde: filename="${0##*/}" scriptpath=`pwd -P` if [ -z "$1" ] then echo echo "Syntax: $scriptpath/$filename " echo echo "CSV-Format: kursID,LehrerID,SchuelerID," echo exit 0; fi ####################################################################### ### Schritt I: Datei wird eingelesen und verarbeitet: read_csv() { rm -f ./$output rm -f ./$output2 while IFS="," read kursID lehrer; do echo "Kurs: $kursID mit Lehrer: $lehrer wird generiert!" #Dialog-Menu benötigt 3 Optionen (on/off per default möglich!) echo -n "sophomorix-project -p p_kurs_$kursID --join --create --admins $lehrer --members " >> $outtemp echo -n "sophomorix-project -p p_kurs_$kursID --kill" >> $outtemp2 while IFS="," read kurs lehrer schueler; do if [[ $kurs == "$kursID" ]]; then echo -n "$schueler," >> $outtemp fi done < <(cat $IDs |tr [:upper:]ÄÖÜ [:lower:]äöü ) #Zeilenumbruch manuell einfügen: echo -en "\n" >> $outtemp echo -en "\n" >> $outtemp2 done < <(cat $IDs | cut -d"," -f1,2 |uniq |tr [:upper:]ÄÖÜ [:lower:]äöü) #Zeilen numerieren in Ausgabefile! awk '{ i += 1; if (length($0) > 0) {print i": "$0} else { print } }' $outtemp > $output awk '{ i += 1; if (length($0) > 0) {print i": "$0} else { print } }' $outtemp2 > $output2 rm -f ./$outtemp rm -f ./$outtemp2 } ######################################################################### ### Untermenu 1 ### create_project() { rm -f /tmp/options #Die Checkliste benötigt drei Parameter: kurs, lehrer, on/off Zaehler=0 while IFS="," read kursID lehrer; do Zaehler=$((Zaehler+1)) echo "$Zaehler $kursID..............$lehrer off" >>/tmp/options done < <(cat $IDs | cut -d"," -f1,2 |uniq |tr [:upper:]ÄÖÜ [:lower:]äöü) OPTIONS=`cat /tmp/options` choices=`/usr/bin/dialog --backtitle "Projekt-Manager $VER" --stdout --checklist 'Anzulegende Projekte auswählen:' 30 55 25 ${OPTIONS}` if [ $? -eq 0 ] then for choice in $choices do #Anführungszeichen los werden: auswahl=$(echo $choice |sed 's/\"//g') while IFS=":" read nummer command; do if [[ $auswahl = "$nummer" ]]; then #Zum Scharfstellen des Scriptes den Befehl "echo" in der folgende Zeile löschen! echo $command fi done < <(cat $output ) done echo "-----------------------------------------------------------------------------------------------" read -p "Any key to return to Menu." else echo "Keine Auswahl! Ende!" fi } ### Untermenu 2 ### delete_project() { rm -f /tmp/options #Die Checkliste benötigt drei Parameter: kurs, lehrer, on/off Zaehler=0 while IFS="," read kursID lehrer; do Zaehler=$((Zaehler+1)) echo "$Zaehler $kursID..............$lehrer off" >>/tmp/options done < <(cat $IDs | cut -d"," -f1,2 |uniq |tr [:upper:]ÄÖÜ [:lower:]äöü) OPTIONS=`cat /tmp/options` choices=`/usr/bin/dialog --backtitle "Projekt-Manager $VER" --stdout --checklist 'Zu löschende Projekte auswählen:' 30 55 25 ${OPTIONS}` if [ $? -eq 0 ] then for choice in $choices do #Anführungszeichen los werden: auswahl=$(echo $choice |sed 's/\"//g') while IFS=":" read nummer command; do if [[ $auswahl = "$nummer" ]]; then #Zum Scharfstellen des Scriptes den Befehl "echo" in der folgende Zeile löschen! echo $command fi done < <(cat $output2 ) done echo "-----------------------------------------------------------------------------------------------" read -p "Any key to return to Menu." else echo "Keine Auswahl! Ende!" fi } ### Hauptmenu ### main_menu() { dialog --backtitle " Sophomorix Projekt-Manager Version: $VER " --title " Hauptmenu "\ --cancel-label "Exit" \ --menu "Cursortasten [UP] [DOWN], [ENTER] zur Auswahl" 10 60 10\ Anlegen "Projekte anlegen"\ Löschen "Projekte löschen"\ Quit "Exit" 2>$_temp opt=${?} if [ $opt != 0 ]; then rm $_temp; exit; fi menuitem=`cat $_temp` echo "menu=$menuitem" case $menuitem in Anlegen) create_project;; Löschen) delete_project;; Quit) rm $_temp; exit;; esac } read_csv while true; do main_menu done